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;
}
}
接口为string定义联合类型|布尔值。
为什么当我将两种可能的类型之一分配给实现接口的 class 内的字段时,类型是固定的?
尽管大多数人的期望是,class 成员并不是 contextually typed 声明要实现或扩展的类型。 class 上的 extends
或 implements
声明对 class 实例的类型没有任何影响。相反,它只是在事后对 superclass 或接口执行 class 的 check。因此,如果您的 class 未能实现或扩展您声明的内容,您将收到编译器警告。但是当涉及到结果类型时,它与完全删除 extends
或 implements
子句一样。不,没有人喜欢这个。
参见microsoft/TypeScript#3667 for the original request to fix this, and there was an attempt at microsoft/TypeScript#6118 but it was eventually abandoned due to some problems with existing libraries; see this comment. There are several open issues about this, including microsoft/TypeScript#32082;如果你想看到这个问题得到解决,你可能想去那个问题并给它一个,但现在我们只需要接受这样一个事实,即 class Foo implements Bar {/*...*/}
对 Foo
的类型具有相同的含义正如 class Foo {/*...*/}
所做的那样。
在您的情况下,这意味着 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
}
}
我不明白为什么会出现错误 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;
}
}
接口为string定义联合类型|布尔值。
为什么当我将两种可能的类型之一分配给实现接口的 class 内的字段时,类型是固定的?
尽管大多数人的期望是,class 成员并不是 contextually typed 声明要实现或扩展的类型。 class 上的 extends
或 implements
声明对 class 实例的类型没有任何影响。相反,它只是在事后对 superclass 或接口执行 class 的 check。因此,如果您的 class 未能实现或扩展您声明的内容,您将收到编译器警告。但是当涉及到结果类型时,它与完全删除 extends
或 implements
子句一样。不,没有人喜欢这个。
参见microsoft/TypeScript#3667 for the original request to fix this, and there was an attempt at microsoft/TypeScript#6118 but it was eventually abandoned due to some problems with existing libraries; see this comment. There are several open issues about this, including microsoft/TypeScript#32082;如果你想看到这个问题得到解决,你可能想去那个问题并给它一个,但现在我们只需要接受这样一个事实,即 class Foo implements Bar {/*...*/}
对 Foo
的类型具有相同的含义正如 class Foo {/*...*/}
所做的那样。
在您的情况下,这意味着 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
}
}