Typescript: Suporte para retornar valores de funções de construtor

Criado em 19 mai. 2017  ·  3Comentários  ·  Fonte: microsoft/TypeScript

Versão 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());

Comportamento esperado:

Eu esperaria que tsc compilasse este código sem erros ou avisos, especialmente considerando que o tipo retornado sempre corresponde ao tipo esperado.

Em JavaScript, é possível que uma função construtora retorne um objeto. Quando isso é feito, o objeto retornado se torna o resultado de toda a expressão new (consulte a etapa 3 nesta documentação MDN para o novo operador ).

Preocupado com os tipos, posso ver por que o compilador TypeScript hesitaria em oferecer suporte a essa peculiaridade da linguagem JavaScript. Afinal, o compilador teria que verificar se o valor explicitamente retornado é o mesmo tipo que seria retornado do construtor se ele retornasse undefined (o caso usual). Acho que isso deve ser apoiado, porque:

  1. TS afirma ser um superconjunto de JS.
  2. Esta é uma técnica de JavaScript útil e popular

    O código acima funciona perfeitamente no Node.js e no navegador:

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

Comportamento real:

tsc emite um erro ao 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

Comentários muito úteis

+1

Especialmente agora que temos Proxy , existem bons comportamentos que podemos implementar retornando um proxy em vez da instância da classe diretamente. Mas isso não será possível a menos que possamos inferir ou especificar o tipo de retorno do construtor.

Todos 3 comentários

O tipo é realmente calculado corretamente, independentemente do que você retornar; o compilador sabe como usar o tipo de retorno quando chamado como uma função e o tipo de instância quando usado como um construtor. o erro é o que precisa ser corrigido para o arquivo .js. o padrão ainda não é permitido para um arquivo .ts (uma vez que erramos no lado conservador aqui).

+1

Especialmente agora que temos Proxy , existem bons comportamentos que podemos implementar retornando um proxy em vez da instância da classe diretamente. Mas isso não será possível a menos que possamos inferir ou especificar o tipo de retorno do construtor.

se você pudesse colocar
get(target, name) {}
e
set(target, name, value) {}
dentro do construtor de classe para substituir os operadores de atribuição de propriedade para (todas as propriedades de) Object / Array, então ... javascript não seria insuficiente.
[Caso contrário, seria suficiente retornar o novo Proxy com as funções de manipulador.]

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

remojansen picture remojansen  ·  3Comentários

MartynasZilinskas picture MartynasZilinskas  ·  3Comentários

blendsdk picture blendsdk  ·  3Comentários

siddjain picture siddjain  ·  3Comentários

DanielRosenwasser picture DanielRosenwasser  ·  3Comentários