TypeScript 类使用联合类型字段实现接口导致错误 (2322)
Posted
技术标签:
【中文标题】TypeScript 类使用联合类型字段实现接口导致错误 (2322)【英文标题】:TypeScript Class Implements Interface with Union Type Field results in Error (2322) 【发布时间】:2021-12-30 10:05:18 【问题描述】:我不明白为什么会出现错误 2322。
请检查以下代码sn-p:
interface Fish
alive: string | boolean;
class FishClass implements Fish
alive = 'Yes'
constructor()
// Type 'boolean' is not assignable to type 'string'.(2322)
this.alive = true;
接口定义了字符串的联合类型|布尔值。
当我将两种可能的类型之一分配给实现接口的类中的字段时,为什么类型是固定的?
【问题讨论】:
【参考方案1】:尽管大多数人的期望,类成员不是contextually typed,因为它们被声明为实现或扩展的类型。类上的extends
或implements
声明对类实例的类型没有任何影响。相反,它只是在事后根据超类或接口对类进行检查。因此,如果您的类未能实现或扩展您声明的内容,您将收到编译器警告。但是当涉及到生成的类型时,它就像您完全删除了 extends
或 implements
子句一样。不,没有人喜欢这个。
请参阅microsoft/TypeScript#3667 以获取解决此问题的原始请求,并尝试在microsoft/TypeScript#6118 但由于现有库的一些问题最终被放弃;见this comment。有几个未解决的问题,包括microsoft/TypeScript#32082;如果你想看到这个问题得到解决,你可能想去那个问题并给它一个?,但现在我们只需要接受这样一个事实:class Foo implements Bar /*...*/
对Foo
的类型与@987654334 具有相同的含义@ 会。
在您的情况下,这意味着class FishClass implements Fish /*...*/
在推断成员的方式方面与class FishClass /*...*/
完全相同。由于alive
属性是用string
值"Yes"
初始化的,因此编译器将其推断为string
类型。稍后当您将true
分配给它时,这是一个错误,因为您不能将boolean
分配给string
。注意string
可以赋值给string | boolean
,所以对FishClass implements Fish
的检查成功;您可以缩小子类型的属性。
目前处理这个问题的正确方法是使用所需的类型手动注释field:
class FishClass implements Fish
alive: string | boolean = 'Yes'; // okay
constructor()
this.alive = true; // okay
Playground link to code
【讨论】:
以上是关于TypeScript 类使用联合类型字段实现接口导致错误 (2322)的主要内容,如果未能解决你的问题,请参考以下文章