打字稿编译误差比较可变枚举成员变量
当我收到错误:打字稿编译误差比较可变枚举成员变量
TS2365: Operator '===' cannot be applied to types 'ExampleState.Unsaved' and 'ExampleState.Saving'.
当针对一个可变成员变量进行比较的枚举:
enum ExampleState {
Unset = -1,
Unsaved = 0,
Saving = 1,
Saved = 2
}
class Example {
private state : ExampleState = ExampleState.Unset;
public Save() {
if (this.state === ExampleState.Unsaved) {
this.BeginSaving();
while (this.state === ExampleState.Saving) { // !error!
this.CommitSave();
}
}
}
private BeginSaving() {
this.state = ExampleState.Saving;
}
private CommitSave() {
this.state = ExampleState.Saved;
}
}
真正的例子是一个异步方法,它多次尝试保存 - 这已被简化为只是说明错误。
Typescript似乎并不明白这个变量是可变的,并且过于积极地假设它没有被改变。为什么会发生这种情况,解决方法是什么?
这是一个know issus from the Control flow analysis。
As another workaround您可以为state属性创建一个包装方法。 (谢谢@Paleo)
访问Playground。
enum ExampleState {
Unset = -1,
Unsaved = 0,
Saving = 1,
Saved = 2
}
class Example {
private state : ExampleState = ExampleState.Unset;
private State() {
return this.state;
}
public Save() {
if (this.State() === ExampleState.Unsaved) {
this.BeginSaving();
while (this.State() === ExampleState.Saving) {
this.CommitSave();
}
}
}
private BeginSaving() {
this.state = ExampleState.Saving;
}
private CommitSave() {
this.state = ExampleState.Saved;
}
}
这是因为ExampleState.Unsaved
不仅是价值,而且还是一种类型(let x: ExampleState.Unsaved
在语义上是有效的)。打字稿有所谓的型后卫,和你的
if (this.state === ExampleState.Unsaved)
说法是这样的控卫 - 打字稿假设this.state
内部的语句总是ExampleState.Unsaved
类型。
我怀疑枚举类型,就像联盟类型实际处理,所以你的代码就相当于(这也不起作用):
type ExampleState = -1 | 0 | 1 | 2;
class Example {
private state : ExampleState = -1;
public Save() {
if (this.state === 0) {
this.BeginSaving();
while (this.state === 1) { // !error!
this.CommitSave();
}
}
}
private BeginSaving() {
this.state = 1;
}
private CommitSave() {
this.state = 2;
}
}
正如@Paleo说,我认为这是值得提交给TypeScript团队(如果尚未由其他人发送)。现在,我建议在您的while
声明中输入铸件。与使用while
的解决方案相比,它可以产生与您最初想要的完全相同的JavaScript输出。
while (this.state as ExampleState === ExampleState.Saving) { // no error
this.CommitSave();
}
理想情况下,有人会在打开一个新的之前搜索相关的问题。正如@Magu所说,这是由[Microsoft/TypeScript#9998](https://github.com/Microsoft/TypeScript/issues/9998)所涵盖。 – jcalz
您可以使用'while(this.state as any === ExampleState.Saving)'作为解决方法。但我建议你[将案例提交给TypeScript团队](https://github.com/Microsoft/TypeScript/issues)。 – Paleo
同样的建议,虽然我宁愿这样做: 'while(this.state as ExampleState === ExampleState.Saving)' –
有一个公开的问题:https://github.com/Microsoft/TypeScript/问题/ 9998 – Magu