TypeScript-Version: 2.2.2
Ich verstehe vielleicht nur falsch, wie Generika funktionieren (wenn ja, weisen Sie mich bitte in die richtige Richtung), aber das scheint ein Fehler zu sein.
Code
// 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'.
}
}
Erwartetes Verhalten:
In der Component
-Klasse im obigen Beispiel verursacht dies keine Fehler, wenn die BaseState
-Schnittstelle direkt verwendet wird. Ich erwarte dasselbe Verhalten von der Klasse GenericComponent
, da das Generikum State
BaseState
explizit erweitert.
Tatsächliches Verhalten:
Stattdessen erhalte ich den folgenden Fehler in Bezug auf this.setState({ on: value > 0 });
: "Das Argument vom Typ '{on: boolean;}' kann nicht dem Parameter vom Typ 'State' zugewiesen werden."
Überlegen Sie, was passiert, wenn Sie dies schreiben
var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't
Hier ist ein vereinfachtes Beispiel:
class Stateful<State extends { on: boolean }> {
state: State = {
on: true
}; // error
}
Der Grund, warum dies nicht funktioniert, ist, dass es immer nur gültig ist, wenn Stateful
mit einem Typargument instanziiert wird, das genau { on: boolean }
.
Grundsätzlich _Es exists_ ein Typ T
, erfüllt die Einschränkungen von Stateful
‚s Typargument , so dass die Instanziierung gültig ist , aber dies gilt nicht _for all_ Arten T
, wo T
erfüllt die Einschränkung des Typarguments Stateful
.
Der obige fehlerhafte Code besagt also, dass für alle Typen T<T>
wobei T,
Stateful
Logischerweise können wir es wie folgt betrachten
Behauptung
P
der Typ { on: boolean }
T
so dass T
P
zuweisbar ist, gilt die Definition von Stateful<T>
obenDisproof durch Gegenbeispiel
U
der Typ { on: boolean, value: number }
U
per Definition P
-> zugewiesen werdenStateful<U>
ist ungültig -> durch ErsetzungT
so dass T
P
zuweisbar ist und Stateful<T>
eine ungültige Instanziierung ist -> implizit@ RyanCavanaugh @aluanhaddad Shoot, das wusste ich. Ich war nur verwirrt, als ich versuchte, das Problem auf etwas Einfacheres zu reduzieren. Versuchen wir es also noch einmal. Was ist in diesem Fall mit einem Partial? Ich erhalte immer noch einen ähnlichen Fehler.
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>'
}
}
Hilfreichster Kommentar
Überlegen Sie, was passiert, wenn Sie dies schreiben