Typescript: Admite devolver valores de funciones constructoras

Creado en 19 may. 2017  ·  3Comentarios  ·  Fuente: microsoft/TypeScript

Versión de TypeScript: 2.3.2

Código

// 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());

Comportamiento esperado:

Esperaría que tsc compile este código sin errores ni advertencias, especialmente considerando que el tipo devuelto siempre coincide con el tipo esperado.

En JavaScript, es posible que una función constructora devuelva un objeto. Cuando se hace esto, el objeto devuelto se convierte en el resultado de la expresión new (consulte el paso 3 en esta documentación de MDN para el nuevo operador ).

Al preocuparme por los tipos, puedo ver por qué el compilador de TypeScript dudaría en admitir esta peculiaridad del lenguaje JavaScript. Después de todo, el compilador tendría que verificar que el valor devuelto explícitamente sea del mismo tipo que devolvería el constructor si hubiera devuelto undefined (el caso habitual). Creo que esto debería ser apoyado, porque:

  1. TS afirma ser un superconjunto de JS.
  2. Esta es una técnica de JavaScript útil y popular

    El código anterior se ejecuta bien en Node.js y en el navegador:

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

Comportamiento real:

tsc emite un error al verificar este código:

$ 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

Comentario más útil

+1

Especialmente ahora que tenemos Proxy , hay buenos comportamientos que podríamos implementar devolviendo un proxy en lugar de la instancia de clase directamente. Pero eso no será posible a menos que podamos inferir o especificar el tipo de retorno del constructor.

Todos 3 comentarios

El tipo está realmente calculado correctamente, independientemente de lo que devuelva; el compilador sabe cómo usar el tipo de retorno cuando se llama como función y el tipo de instancia cuando se usa como constructor. el error es lo que debe abordarse para el archivo .js. el patrón todavía no está permitido para un archivo .ts (ya que allí cometemos un error en el lado conservador).

+1

Especialmente ahora que tenemos Proxy , hay buenos comportamientos que podríamos implementar devolviendo un proxy en lugar de la instancia de clase directamente. Pero eso no será posible a menos que podamos inferir o especificar el tipo de retorno del constructor.

si pudieras poner
get(target, name) {}
y
set(target, name, value) {}
dentro del constructor de la clase para anular los operadores de asignación de propiedad para (todas las propiedades de) Object / Array, entonces bueno ... javascript no se quedaría corto.
[De lo contrario, sería suficiente devolver el nuevo Proxy con las funciones del controlador].

¿Fue útil esta página
0 / 5 - 0 calificaciones