Я использую React.js с TypeScript. Есть ли способ создать компоненты React, которые наследуются от других компонентов, но имеют некоторые дополнительные реквизиты/состояния?
То, что я пытаюсь достичь, выглядит примерно так:
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
}
}
Однако это произойдет, если я вызову this.setState
в Derived
, я получаю ошибку TypeScript (параметр типа DerivedStates
не может быть назначен типу S
). Я полагаю, что это не TypeScript -специфическая вещь, а общее ограничение смешивания наследования с дженериками (?). Есть ли безопасный способ для этого?
UPDATE
Решение, на котором я остановился (на основе ответа Дэвида Шеррета):
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 });
}
}