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
constou propriedadereadonlysem uma anotação de tipo é o tipo do inicializador como está.
enquanto
- O tipo inferido para uma variável
let, variávelvar, parâmetro ou propriedade nãoreadonlycom 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.