Typescript: Es ist nicht möglich, einer generischen typisierten Eigenschaft einen kompatiblen Wert zuzuweisen, indem in der generischen Definition "erweitert" verwendet wird.

Erstellt am 7. Apr. 2017  ·  3Kommentare  ·  Quelle: microsoft/TypeScript

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."

Question

Hilfreichster Kommentar

Ü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

Alle 3 Kommentare

Ü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

  1. Sei P der Typ { on: boolean }
  2. Für alle Typen T so dass T P zuweisbar ist, gilt die Definition von Stateful<T> oben

Disproof durch Gegenbeispiel

  1. Sei U der Typ { on: boolean, value: number }
  2. U per Definition P -> zugewiesen werden
  3. Stateful<U> ist ungültig -> durch Ersetzung
  4. Daher gibt es einen Typ T 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>'
    }
}
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

tenry92 picture tenry92  ·  146Kommentare

fdecampredon picture fdecampredon  ·  358Kommentare

xealot picture xealot  ·  150Kommentare

Gaelan picture Gaelan  ·  231Kommentare

yortus picture yortus  ·  157Kommentare