TypeScript Version: 2.2.2
Saya mungkin saja salah paham tentang cara kerja obat generik (jika demikian, tolong arahkan saya ke arah yang benar), tetapi ini sepertinya bug.
Kode
// A *self-contained* demonstration of the problem follows...
interface BaseState {
on: boolean;
};
class Component {
state: BaseState;
setState(state: BaseState) {
this.state = state;
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // no error
}
}
class GenericComponent<State extends BaseState> {
state: State;
setState(state: State) {
this.state = state
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error Argument of type '{ on: boolean; }' is not assignable to parameter of type 'State'.
}
}
Perilaku yang diharapkan:
Dalam kelas Component
pada contoh di atas tidak menyebabkan kesalahan saat menggunakan antarmuka BaseState
secara langsung. Saya mengharapkan perilaku yang sama dari kelas GenericComponent
karena State
generik secara eksplisit memperluas BaseState
.
Perilaku sebenarnya:
Sebaliknya saya mendapatkan kesalahan berikut terkait dengan this.setState({ on: value > 0 });
: "Argumen tipe '{on: boolean;}' tidak dapat dialihkan ke parameter tipe 'Status'."
Pertimbangkan apa yang terjadi jika Anda menulis ini
var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't
Berikut adalah contoh yang disederhanakan:
class Stateful<State extends { on: boolean }> {
state: State = {
on: true
}; // error
}
Alasan ini tidak berhasil adalah karena ini hanya akan valid ketika Stateful
dibuat dengan argumen tipe yang sama persis dengan { on: boolean }
.
Pada dasarnya, _ terdapat_ tipe T
, memenuhi batasan dari argumen tipe Stateful
sedemikian rupa sehingga instansiasi valid tetapi ini tidak berlaku _untuk semua_ tipe T
dimana T
memenuhi batasan dari argumen tipe Stateful
.
Jadi kode yang salah di atas menegaskan bahwa, untuk semua jenis T<T>
mana T,
Stateful
Logikanya, kita bisa melihatnya sebagai berikut
Tuntutan
P
menjadi tipe { on: boolean }
T
sehingga T
dapat dialihkan ke P
, definisi Stateful<T>
atas berlakuDisproof dengan contoh counter
U
menjadi tipe { on: boolean, value: number }
U
dapat dialihkan ke P
-> menurut definisiStateful<U>
tidak valid -> dengan substitusiT
sehingga T
dapat dialihkan ke P
dan Stateful<T>
adalah contoh yang tidak valid -> implikasinya@RyanCavanaugh @aluanhaddad Tembak, aku tahu itu. Saya baru saja bingung saat mencoba menyaring masalah menjadi sesuatu yang lebih sederhana. Jadi, coba lagi. Bagaimana jika dalam kasus ini menggunakan Partial? Saya masih mendapatkan kesalahan serupa.
interface BaseState {
on: boolean;
};
class Component {
state: BaseState;
setState(partialState: Partial<BaseState>) {
this.state = { ...this.state, ...partialState };
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // no error
}
}
class GenericComponent<State extends BaseState> {
state: State;
setState(partialState: Partial<State>) {
this.state = { ...this.state, ...partialState };
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
}
}
Komentar yang paling membantu
Pertimbangkan apa yang terjadi jika Anda menulis ini