2015-09-30 16 views
17

React.jsをTypeScriptで使用しています。他のコンポーネントから継承するが、いくつかの追加の小道具/状態を持つReactコンポーネントを作成する方法はありますか?私が達成しようとしている何TypeScriptのReactコンポーネントを拡張する

は、このようなものです:私はDerivedthis.setStateを呼び出す場合は、これは失敗します

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 
    } 
} 

、私は活字体のエラーを取得する(タイプDerivedStatesのパラメータは型に代入ではありませんS)。私はこれがTypeScript特有のものではないが、継承をジェネリック(?)と混合するという一般的な制限があると思います。このための型安全な回避策はありますか?

UPDATE

(デビッドSherretの回答に基づいて)私は上の和解解決策:あなたが使用してDerivedに一度状態の唯一のいくつかのプロパティを設定することができ

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 }); 
    } 
} 

答えて

10

型アサーション:ところで

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

getInitialStateに異なる名前を持ってする必要はありません...あなただけでもできます:

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

クイックアンサーに感謝します。あなたのソリューションについては、コンストラクタの2行目にエラーが発生します: 'type 'BaseStates'は 'S'型に割り当てられません ' S'は 'BaseStates'のサブクラスなので、驚くことではありません。 。 – Thegaram

+0

@Thegaram私はちょうどそれを修正していた。今修正されました。 –

+0

ありがとう!これらのダウンキャストがどれほど安全かについてはまだ分かりませんが、私の質問には答えられます。 – Thegaram

関連する問題