我收到错误:
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似乎并不明白这个变量是可变的,并且过于积极地假设它没有被改变。为什么会发生这种情况以及解决方法是什么?
答案 0 :(得分:2)
这是know issus from the Control flow analysis。
作为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;
}
}
答案 1 :(得分:0)
它正在发生,因为ExampleState.Unsaved
不仅是值,而且是类型(let x: ExampleState.Unsaved
在语义上有效)。打字稿有所谓的打样,你的
if (this.state === ExampleState.Unsaved)
语句就是这种保护 - 在该语句中,typescript假定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();
}