No entiendo por qué se produce el error 2322.
Examine el siguiente fragmento de código:
interface Fish { alive: string | boolean; } class FishClass implements Fish { alive = 'Yes' constructor() { // Type 'boolean' is not assignable to type 'string'.(2322) this.alive = true; } }La interfaz define el tipo de unión para cadena | booleano
¿Por qué se corrige el tipo cuando asigné uno de los dos tipos posibles al campo dentro de la clase que implementa la interfaz?
A pesar de las expectativas de la mayoría de las personas, los miembros de la clase no están tipificados contextualmente por los tipos que se declara que implementarán o extenderán. Una declaración de extends o implements en una clase no tiene ningún efecto sobre el tipo de instancia de la clase. En cambio, solo hace una verificación de la clase contra la superclase o la interfaz después del hecho. Entonces, si su clase no implementa o amplía lo que ha declarado, recibirá una advertencia del compilador. Pero cuando se trata de los tipos resultantes, será lo mismo que si eliminara por completo la cláusula extends o implements . No, a nadie le gusta esto.
Consulte microsoft/TypeScript#3667 para conocer la solicitud original para corregir esto, y hubo un intento en microsoft/TypeScript#6118 pero finalmente se abandonó debido a algunos problemas con las bibliotecas existentes; ver este comentario . Hay varios problemas abiertos al respecto, incluidos microsoft/TypeScript#32082 ; si quieres que esto se aborde, es posible que quieras ir a ese problema y darle un 👍, pero por ahora solo tenemos que vivir con el hecho de que la class Foo implements Bar {/*...*/} tiene las mismas implicaciones para el tipo de Foo como lo hace class Foo {/*...*/} .
En su caso, eso significa que la class FishClass implements Fish {/*...*/} actúa exactamente como class FishClass {/*...*/} cuando se trata de cómo se infieren los miembros. Dado que la propiedad alive se inicializa con un valor de string de "Yes" , el compilador infiere que es de tipo string . Y luego, cuando le asigna true , es un error porque no puede asignar un boolean a una string . Tenga en cuenta que la string se puede asignar a la string | boolean , por lo que la verificación en FishClass implements Fish tiene éxito; se le permite restringir las propiedades de los subtipos.
La forma correcta de lidiar con esto por ahora es anotar manualmente el campo con el tipo deseado:
class FishClass implements Fish { alive: string | boolean = 'Yes'; // okay constructor() { this.alive = true; // okay } }