oop - TypeScript'te React bileşenlerini genişletme
TypeScript ile React.js kullanıyorum. Başka bileşenlerden miras alan ama bazı ek prop/stanlere sahip React bileşenleri oluşturmanın bir yolu var mı?
Başarmaya çalıştığım şey şöyle bir şey:
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
}
}
Ancak, Derived'de this.setState çağırırsam bu başarısız olacak, TypeScript hatası alıyorum (tipi DerivedStates olan parametre, tipi S olan parametereye atanamaz). Sanırım bu TypeScript'e özgü bir şey değil, ama generikler ile kalıtımı karıştırmanın genel bir sınırlaması (?). Bunun için tip güvenli bir çözüm yolu var mı?
GÜNCELLEME
Benim karar verdiğim çözüm (David Sherret'in cevabına dayanarak):
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 });
}
}
Cevap #1
Bir tür ataması kullanarak Derived içinde aynı anda yalnızca birkaç durum özelliğini ayarlayabilirsiniz:
this.setState({ b: 4 } as DerivedStates); // do this
this.setState({ a: 7 } as DerivedStates); // or this
this.setState({ a: 7, b: 4 }); // or this
Bu arada, getInitialState için farklı isimler kullanmanıza gerek yok... sadece şunu yapabilirsiniz:
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;
}
}
