Sie können direkt keine Parent
zu einem Child
einfach werfen, da der Compiler keine Möglichkeit hat, zu wissen, dass Ihre Parent
Instanz wirklich ein Child
ist. Verwenden Sie einen Typ-Schutz anstelle eines Darstellers:
class Parent {
prop: string|null = null;
isChild(): this is Child {
return (this as any).otherProp !== undefined;
}
}
class Child extends Parent
{
otherProp: string|null = null;
}
function test(p: Parent) {
if (p.isChild()) {
console.log(p.otherProp);
}
}
Im Inneren des bewachten if
nun der Compiler weiß, dass p
ein Child
ist, außerhalb noch p
ist nur ein Parent
.
Oder noch besser, überschreiben die Wache in der Unterklasse und Sie können dabei jede Schublade gesteckt gar vermeiden:
class Parent {
prop: string|null = null;
isChild(): this is Child {
return false;
}
}
class Child extends Parent
{
otherProp: string|null = null;
isChild(): this is Child { return true; }
}
function test(p: Parent) {
if (p.isChild()) {
console.log(p.otherProp);
}
}
Sie sind richtig, aber, dass ich nicht die Frage beantwortet haben, ob dies ein Fehler oder vorsätzlichen seitens der Typescript-Autoren. Meine Vermutung ist, dass sie versuchen, mögliche Fehler zu finden, aber ich habe keine Erklärung für genau dieses Verhalten gefunden, das es bestätigen oder leugnen würde.
Eine weitere Möglichkeit, Ihre Original-Code Arbeit machen kann, ist ausdrücklich die Art der this
im castToChild
Methode Typoskript zu sagen:
class Parent {
prop: string|null = null;
castToChild(this: Parent): Child{
return this as Child;
}
}
class Child extends Parent
{
otherProp: string|null = null;
}
function foo() {
let p: Parent = new Child();
let c = p.castToChild();
console.log(c.otherProp);
}
Dies ist immer noch wirklich nur die doppelte Besetzung zu tun, sieht aber vielleicht ein bisschen sauberer . Es zeigt jedoch immer noch die Fremdheit des Verhaltens, da ohne den expliziten this
Parameter this
vom Typ Parent
, aber nicht direkt gießbar ist, mit dem expliziten Parameter können Sie es umsetzen.
Sorry, aber ich sehe Ihre Lösung als zu kompliziert. Meine Problemumgehungen mit Zwischenvariablen oder Double-Cast sind viel kürzer und erfordern keinen zusätzlichen Code. Sie erzeugen jedoch nur unnötiges syntaktisches Rauschen. Ich stimme zu, dass der Compiler nicht weiß, dass das Elternteil wirklich ein Kind ist, aber das ist genau der Grund, warum ich Casting mache - um zu sagen, dass ich es besser weiß. –
Interessante Ansicht. Sicherlich liegt der Sinn von Typoskript darin, dass Sie es manchmal nicht besser wissen und der Compiler Ihnen sagen kann, wenn Sie einen Fehler machen. Wenn Sie immer besser als der Compiler wissen, warum nicht einfach Javascript verwenden und sich nicht um diese Typen kümmern müssen? – Duncan
Es tut mir leid, wenn meine Antwort dich irgendwie beleidigt hat, es war sicherlich nicht meine Absicht. Aber dein Vorschlag ist es immer noch nicht die Antwort auf meine Frage: "Warum akzeptiert der TS-Compiler die Besetzung als Doppelbesetzung oder mit der Zwischenvariable, aber nicht auf dem direkten Weg?" Gehen Sie den gleichen Weg mit zwei Schritten statt einer ist, was ich "syntaktischen Lärm" genannt –