Typescript: Prise en charge des valeurs renvoyées par les fonctions du constructeur

Créé le 19 mai 2017  ·  3Commentaires  ·  Source: microsoft/TypeScript

Version TypeScript: 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());

Comportement prévisible:

Je m'attendrais tsc ce que

En JavaScript, il est possible pour une fonction constructeur de renvoyer un objet. Lorsque cela est fait, l'objet retourné devient le résultat de l'expression entière new (voir l'étape 3 dans cette documentation MDN pour le nouvel opérateur ).

Étant préoccupé par les types, je peux voir pourquoi le compilateur TypeScript hésiterait à prendre en charge cette bizarrerie du langage JavaScript. Après tout, le compilateur devrait vérifier que la valeur explicitement retournée est du même type que celle qui serait retournée par le constructeur s'il avait renvoyé undefined (le cas habituel). Je pense que cela devrait être soutenu, car:

  1. TS prétend être un sur-ensemble de JS.
  2. Il s'agit d'une technique JavaScript utile et populaire

    Le code ci-dessus fonctionne très bien dans Node.js et dans le navigateur:

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

Comportement réel:

tsc émet une erreur lors de la vérification de ce code:

$ 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

Commentaire le plus utile

+1

Surtout maintenant que nous avons Proxy , il y a de bons comportements que nous pourrions implémenter en renvoyant directement un proxy au lieu de l'instance de classe. Mais cela ne sera possible que si nous pouvons déduire ou spécifier le type de retour du constructeur.

Tous les 3 commentaires

Le type est en fait correctement compris, peu importe ce que vous retournez; le compilateur sait utiliser le type de retour lorsqu'il est appelé en tant que fonction, et le type d'instance lorsqu'il est utilisé en tant que constructeur. l'erreur est ce qui doit être résolu pour le fichier .js. le modèle n'est toujours pas autorisé pour un fichier .ts (puisque nous nous trompons du côté conservateur).

+1

Surtout maintenant que nous avons Proxy , il y a de bons comportements que nous pourrions implémenter en renvoyant directement un proxy au lieu de l'instance de classe. Mais cela ne sera possible que si nous pouvons déduire ou spécifier le type de retour du constructeur.

si tu pouvais mettre
get(target, name) {}
et
set(target, name, value) {}
à l'intérieur du constructeur de classe pour remplacer les opérateurs d'affectation de propriété pour (toutes les propriétés de) Object / Array, alors bien ... javascript ne serait pas court.
[Sinon, il suffirait de renvoyer le nouveau proxy avec les fonctions de gestion.]

Cette page vous a été utile?
0 / 5 - 0 notes