打字稿:如何在联合类型中为枚举添加类型保护?

时间:2015-04-17 18:15:13

标签: types enums typescript

以下代码给出了错误:

  1. 'instanceof'表达式的左侧必须是'any'类型,对象或类型参数。
  2. 输入'E | C'不能分配给'E'类型。类型“C”不能分配给“E”类型。
  3.     enum E { FIRST = 1, SECOND = 2 }; 
    
        class C {
            value: E;    
    
            constructor(arg: C | E) {
                if (arg instanceof C) { // 1.
                    this.value = arg.value;
                } else {
                   this.value = arg; // 2.
                }
            }
        }
    
        var a: C = new C(E.SECOND);
        console.log('a.value = ' + a.value);
    
        var b: C = new C(a);
        console.log('b.value = ' + b.value);
    

    尽管有错误,代码似乎在TypeScript Playground上正常编译并且符合预期。

2 个答案:

答案 0 :(得分:6)

两个问题。

编译器中存在一个错误,当其中一个成分不是对象类型时,联合类型不允许instanceof。这是固定的(https://github.com/Microsoft/TypeScript/issues/2775

另一件事是instanceof不会导致else块(https://github.com/Microsoft/TypeScript/issues/1719)缩小,因为instanceof检查失败不一定 表示对象与指定的接口不匹配。这是目前“按设计”,但我鼓励你留下评论,你发现这种行为令人惊讶或不受欢迎(我当然这样做)。

答案 1 :(得分:3)

当然,Ryan既雄辩又准确,但我可以为您提供一个您可能觉得有用的临时解决方法。尽管有可能使用,但请不要接受这个作为答案,因为长期来看,类型防护相关问题的解决方案会更好。

class C {
    value: E;    

    constructor(arg: C | number) {
        if(typeof arg === 'number') {
            this.value = arg;
        } else {
            this.value = arg.value;
        }
    }
}

这种相当令人讨厌的解决方案依赖于枚举和数字愉快地共同发挥作用的事实。您还可以从typeof检查缩小else语句的副作用中受益。