TypeScript错误转换接口联合字段

时间:2017-12-25 09:09:58

标签: typescript

这是产生错误的最小代码:

interface A1 {
    type: "A1";
}
interface A2 {
    type: "A2";
}
type AU = A1 | A2;

function foo(obj1: AU) {
    const obj2: AU = {
        type: obj1.type
        /*
        Error TS2322:
        Type '{ type: "A1" | "A2"; }' is not assignable to type 'AU'.
            Type '{ type: "A1" | "A2"; }' is not assignable to type 'A2'.
            Types of property 'type' are incompatible.
            Type '"A1" | "A2"' is not assignable to type '"A2"'.
            Type '"A1"' is not assignable to type '"A2"'.
        */
    };
}

这是TypeScript错误吗? (我在他们的GitHub上发布了这个问题#20889)

或者我在某种程度上没有正确使用这些工具?

2 个答案:

答案 0 :(得分:3)

obj2声明中删除类型部分 - const obj2 = { type: obj1.type }时,obj2的类型设置为{ type: 'A1' | 'A2' },代码编译正确。

使用此语句代码也可以正确编译,类型设置为AU

let obj2 = { type: obj1.type } as AU

答案 1 :(得分:1)

问题是,它试图创建一个类型为" A1"的对象。 | " A2"在将其分配给obj2之前。

所以{ type: "A1" | "A2"; }实际上是暂时存在的未命名类型(并且您无法分配给AU)。

通常的用例是A1和A2都有几个属性需要初始化,所以如果你要创建一个if-then-else代码,它会正确地检测到这个类型{输入:" A1&#34 ;;}或{type:" A&#34 ;;}

function foo(obj1: AU) {
    // No errors:
    if(obj1.type === 'A1') {
        const obj2: AU = { type: obj1.type /* further attributes here*/ };
    } else if(obj1.type === 'A2') {
        const obj2: AU = { type: obj1.type /* further attributes here*/ };
    }
}

我非常怀疑微软是否会对此问题采取任何措施,因为它可能需要对解析器的工作方式进行更深入的重写。