TypeScript: statiska egenskaper och arv
Jag är ganska ny på TypeScript (1.8) och jag har ett litet problem med arv och statiska egenskaper.
Vänligen hitta nedan testkoden jag för närvarande kör:
class A {
public static Items = {
FOO: 'A'
};
public show() {
alert(this.constructor.Items.FOO);
}
}
class B extends A {
public static Items = {
FOO: 'B'
};
}
var a = new A();
var b = new B();
a.show(); // alert "A"
b.show(); // alert "B"
TypeScript Playground-länk
Den här koden fungerar bra och de två varningarna visas som förväntat.
MEN TypeScript-kompilatorn ger ett fel: Property "Items" finns inte på typen "Function"
Jag förstår varningen och den är helt rätt ur ett TypeScript-perspektiv, men hur kan jag uppnå samma resultat samtidigt som kompilatorn blir nöjd? this.Items.FOO fungerar uppenbarligen inte och jag har inte hittat någon self-ekvivalent eller något liknande...
Missar jag något?
Tack i förväg!
Svar #1
Det fanns en liknande fråga idag: Referera till klass utan namn för att använda olika statiska metoder i underklasser i TypeScript.
Det finns en diskussion/förslag om att ha this.constructor som returnerar rätt typ här: T.constructor borde vara av typ T.
När det gäller möjliga lösningar för dig för tillfället:
Utan alls statisk:
class A {
public show() {
alert(this.getItems().FOO);
}
protected getItems() {
return {
FOO: 'A'
}
};
}
class B extends A {
protected getItems() {
return {
FOO: 'B'
}
}
}
(kod i lekplats)
Statisk med typeof:
class A {
public static Items = {
FOO: 'A'
};
public show() {
alert((<typeof A | typeof B> this.constructor).Items.FOO);
}
}
(kod i lekplats)
Statisk med konstruktörgränssnitt:
interface AConstructor {
new (): A;
Items: any;
}
class A {
public static Items = {
FOO: 'A'
};
public show() {
alert((this.constructor as AConstructor).Items.FOO);
}
}
(kod i lekplats)
Svar #2
Jag förstår varningen och den är helt korrekt från ett TypeScript-perspektiv
Rätt - detta är något som liknar arv, men det fungerar inte och bör generellt sett inte fungera för dina statiska egenskaper. För att komma runt detta, inaktivera typkontroll genom att använda any:
alert((<any>this.constructor).Items.FOO);
Denna situation uppstår ofta när man konverterar gammal js-kod, men bör undvikas när man skriver ny TS-kod. Om du vill göra detta korrekt skulle du behöva (som du förmodligen är medveten om) implementera och överskrida en getItems eller liknande metod i dina två klasser för att returnera motsvarande Items, och kalla på den metoden från show.
