Typescript: Unterstützt die Rückgabe von Werten aus Konstruktorfunktionen

Erstellt am 19. Mai 2017  ·  3Kommentare  ·  Quelle: microsoft/TypeScript

TypeScript-Version: 2.3.2

Code

// example.js

var Person = function (firstNameOrPojo, lastName) {

    if (typeof firstNameOrPojo === "string") {
        this.firstName = firstNameOrPojo;
        this.lastName = lastName;
    } else {
        return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName);
    }
};

Person.prototype.greet = function greet() {
    return `Hello, I am ${this.firstName} ${this.lastName}.`;
};

var fred = new Person({firstName: "Fred", lastName: "Flintstone"});

console.log(fred.greet());

Erwartetes Verhalten:

Ich würde erwarten, dass tsc diesen Code ohne Fehler oder Warnungen kompiliert, insbesondere wenn man bedenkt, dass der zurückgegebene Typ immer mit dem erwarteten Typ übereinstimmt.

In JavaScript kann eine Konstruktorfunktion ein Objekt zurückgeben. Wenn dies erledigt ist, wird das zurückgegebene Objekt das Ergebnis des gesamten Ausdrucks new (siehe Schritt 3 in dieser MDN-Dokumentation für den neuen Operator ).

Wenn ich mich mit Typen befasse, kann ich sehen, warum der TypeScript-Compiler zögert, diese Eigenart der JavaScript-Sprache zu unterstützen. Schließlich müsste der Compiler überprüfen, ob der explizit zurückgegebene Wert derselbe Typ ist, der vom Konstruktor zurückgegeben würde, wenn er undefined (der übliche Fall). Ich denke, dies sollte unterstützt werden, weil:

  1. TS behauptet, eine Obermenge von JS zu sein.
  2. Dies ist eine nützliche und beliebte JavaScript-Technik

    Der obige Code läuft in Node.js und im Browser einwandfrei:

$ node example.js
Hello, I am Fred Flintstone.

Tatsächliches Verhalten:

tsc gibt beim Überprüfen dieses Codes einen Fehler aus:

$ tsc --allowJs --checkJs --outDir ./dist example.js
example.js(8,16): error TS2350: Only a void function can be called with the 'new' keyword.
Bug Fixed

Hilfreichster Kommentar

+1

Besonders jetzt, wo wir Proxy , gibt es nette Verhaltensweisen, die wir implementieren könnten, indem wir einen Proxy anstelle der Klasseninstanz direkt zurückgeben. Dies ist jedoch nur möglich, wenn wir den Rückgabetyp des Konstruktors ableiten oder angeben können.

Alle 3 Kommentare

Der Typ ist tatsächlich richtig herausgefunden, unabhängig davon, was Sie zurückgeben. Der Compiler kann den Rückgabetyp verwenden, wenn er als Funktion aufgerufen wird, und den Instanztyp, wenn er als Konstruktor verwendet wird. Der Fehler ist, was für die .js-Datei behoben werden muss. Das Muster ist für eine .ts-Datei immer noch nicht zulässig (da wir dort auf der konservativen Seite Fehler machen).

+1

Besonders jetzt, wo wir Proxy , gibt es nette Verhaltensweisen, die wir implementieren könnten, indem wir einen Proxy anstelle der Klasseninstanz direkt zurückgeben. Dies ist jedoch nur möglich, wenn wir den Rückgabetyp des Konstruktors ableiten oder angeben können.

wenn du setzen könntest
get(target, name) {}
und
set(target, name, value) {}
Innerhalb des Klassenkonstruktors, um Eigenschaftszuweisungsoperatoren für (alle Eigenschaften von) Object / Array zu überschreiben, würde Javascript nicht zu kurz kommen.
[Andernfalls würde es ausreichen, den neuen Proxy mit den Handlerfunktionen zurückzugeben.]

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen