oop - Utvide React-komponenter i TypeScript
Jeg bruker React.js med TypeScript. Finnes det en måte å lage React-komponenter som arver fra andre komponenter, men som har noen ekstra props/states?
Det jeg prøver å oppnå er noe sånt som dette:
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
}
}
Men dette vil feile hvis jeg kaller this.setState i Derived, jeg får en TypeScript-feil (parameter av typen DerivedStates kan ikke tildeles til typen S). Jeg antar at dette ikke er spesifikt for TypeScript, men en generell begrensning ved å blande arv med generiske typer (?). Finnes det noen typesikre løsninger på dette?
OPPDATERING
Løsningen jeg valgte (basert på svaret til 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 });
}
}
Svar #1
Du kan sette bare noen få egenskaper av tilstanden samtidig i Derived ved å bruke en typepåstand:
this.setState({ b: 4 } as DerivedStates); // do this
this.setState({ a: 7 } as DerivedStates); // or this
this.setState({ a: 7, b: 4 }); // or this
Forresten, ingen grunn til å ha forskjellige navn for getInitialState... du kan bare gjøre:
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;
}
}
