繁体   English   中英

TypeScript Class 使用联合类型字段实现接口导致错误 (2322)

[英]TypeScript Class Implements Interface with Union Type Field results in Error (2322)

我不明白为什么会发生错误 2322。

请检查以下代码片段:

interface Fish {
  alive: string | boolean;
}

class FishClass implements Fish {
  alive  = 'Yes'

  constructor() {
    // Type 'boolean' is not assignable to type 'string'.(2322)
    this.alive = true; 
  }
}

该接口定义了字符串 | 的联合类型。 boolean。

为什么当我将两种可能的类型之一分配给实现接口的 class 内的字段时,类型是固定的?

尽管有大多数人的期望,class 成员并没有按照它们声明要实现或扩展的类型进行上下文类型化 class 上的extendsimplements声明对 class 实例的类型没有任何影响。 相反,它只是在事后针对超类或接口检查class。 因此,如果您的 class 无法实现或扩展您声明的内容,您将收到编译器警告。 但是当涉及到生成的类型时,它就像您完全删除了extendsimplements子句一样。 不,没有人喜欢这个。

有关修复此问题的原始请求,请参阅microsoft/TypeScript#3667 ,并且尝试microsoft/TypeScript#6118但由于现有库的一些问题最终被放弃; 看到这个评论 有几个未解决的问题,包括microsoft/TypeScript#32082 如果您想看到此问题得到解决,您可能希望 go 解决该问题并给出它,但现在我们只需要接受class Foo implements Bar {/*...*/}具有相同含义的事实Foo的类型就像class Foo {/*...*/}一样。


在您的情况下,这意味着class FishClass implements Fish {/*...*/}在推断成员的方式方面与class FishClass {/*...*/} /*...*/} 的行为完全相同。 由于alive属性是用string"Yes"初始化的,因此编译器推断它是string类型。 稍后当您为其分配true时,这是一个错误,因为您无法将boolean分配给string 请注意, string可分配给string | boolean string | boolean ,所以对FishClass implements Fish的检查成功; 您可以缩小子类型的属性。

目前处理这个问题的正确方法是使用所需的类型手动注释字段

class FishClass implements Fish {
   alive: string | boolean = 'Yes'; // okay

   constructor() {
      this.alive = true; // okay
   }
}

Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM