2015-09-30 16 views
17

Ich verwende React.js mit TypeScript. Gibt es eine Möglichkeit, React-Komponenten zu erstellen, die von anderen Komponenten erben, aber zusätzliche Requisiten/Zustände haben?Erweitern React-Komponenten in TypeScript

Was ich versuche, so etwas zu erreichen ist:

interface BaseStates { 
    a: number; 
} 

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    protected getBaseInitialState(): BaseStates { 
     return { a: 3 }; 
    } 
} 

class Base extends GenericBase<BaseStates> { 
    getInitialState(): BaseStates { 
     return super.getBaseInitialState(); 
    } 
} 

interface DerivedStates extends BaseStates { 
    b: number; 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState(): DerivedStates { 
     var initialStates = super.getBaseInitialState() as DerivedStates; // unsafe?? 
     initialStates.b = 4; 
     return initialStates 
    } 
} 

Dies wird jedoch fehlschlagen, wenn ich this.setState in Derived nennen, erhalte ich eine Typoskript Fehler (Parameter vom Typ DerivedStates ist nicht übertragbar auf den Typ S). Ich nehme an, das ist keine Typ-Script-spezifische Sache, sondern eine generelle Einschränkung der Mischvererbung mit Generika (?). Gibt es eine typsichere Abhilfe dafür?

UPDATE

Die Lösung, die ich auf abgewickelte (bezogen auf die Antwort von David Sherret):

interface BaseStates { 
    a: number; 
} 

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    constructor() { 
     super(); 
     this.state = this.getInitialState(); 
    } 

    getInitialState(): S { 
     return { a: 3 } as S; 
    } 

    update() { 
     this.setState({ a: 7 } as S); 
    } 
} 

interface DerivedStates extends BaseStates { 
    b: number; 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState(): DerivedStates { 
     var initialStates = super.getInitialState(); 
     initialStates.b = 4; 
     return initialStates; 
    } 

    update() { 
     this.setState({ a: 7, b: 4 }); 
    } 
} 

Antwort

10

Sie sofort in Derived ein nur ein paar Eigenschaften des Staates setzen kann durch die Verwendung Typ Behauptung:

this.setState({ b: 4 } as DerivedStates); // do this 
this.setState({ a: 7 } as DerivedStates); // or this 
this.setState({ a: 7, b: 4 });   // or this 

By the way, keine Notwendigkeit, unterschiedliche Namen für getInitialState ... können Sie einfach tun:

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    constructor() { 
     super();   
     this.state = this.getInitialState(); 
    } 

    protected getInitialState() { 
     return { a: 3 } as BaseStates as S; 
    } 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState() { 
     var initialStates = super.getInitialState(); 
     initialStates.b = 4; 
     return initialStates; 
    } 
} 
+0

Danke für die schnelle Antwort. Für Ihre Lösung erhalte ich einen Fehler für die zweite Zeile des Konstruktors: 'type 'BaseStates' ist nicht dem Typ 'S'' zuweisbar, was nicht überraschend ist, da' S' eine Unterklasse von 'BaseStates' ist . – Thegaram

+0

@Thegaram Ich habe gerade das repariert. Jetzt behoben. –

+0

Danke! Ich bin mir immer noch nicht sicher, wie sicher diese Niedergeschlagenen sind, aber meine Frage ist beantwortet. – Thegaram

Verwandte Themen