Pesquisa de site

typescript - Tipo inferido a partir de propriedade de classe somente leitura


Dada a seguinte classe de teste:

class Test {
    private readonly testString = "hello";
    private readonly testStringImplicit: string = "hello";

    public constructor() {
        this.testString = "world";
        this.testStringImplicit = "world";
    }
}

Atualmente, o Typescript 2.8.2 (e até mesmo o atual 2.9.2) produz o seguinte erro para a primeira propriedade testString:

TS2322: Type "world" is not assignable to type "hello".

Minha Pergunta: Isso é um bug?

Acho que não, mas não entendo por que o tipo da propriedade somente leitura pode ser o valor deles.

Obrigado por cada resposta útil

Resposta #1

É um pouco confuso, mas o tipo do seu testString não é string, é "hello", o tipo literal de string com a sequência de caracteres h, e, l, l, o. Seu testStringImplicit é explicitamente tipado como string, então você pode atribuir qualquer string a ele, mas seu testString só pode ter aquele único valor literal de string.

Ele tem esse tipo porque é readonly, e essa é a string com a qual você o inicializou. Se não fosse readonly, o tipo inferido seria string, mas como é readonly, o tsc está assumindo que a inicialização é o único lugar onde você vai escrever nele, e portanto dá a ele o "melhor tipo comum" para "hello", que é o tipo literal de string.

Como jcalz aponta de maneira útil, este é um comportamento intencional. O ponto relevante desse link:

  • O tipo inferido para uma variável const ou propriedade readonly sem uma anotação de tipo é o tipo do inicializador como está.

enquanto

  • O tipo inferido para uma variável let, variável var, parâmetro ou propriedade não readonly com um inicializador e sem anotação de tipo é o tipo literal ampliado do inicializador.

A palavra "constructor" não aparece no texto daquele pull request, então esse efeito de você não poder atribuir um valor diferente a testString no construtor, mesmo que você tenha permissão para isso pelas regras do readonly, não parece ser discutido lá. Pode ser que seja discutido em outro lugar.

Artigos relacionados