TypeScript Object.assign混淆

时间:2016-10-06 21:43:43

标签: typescript

当我查看signature of Object.assign时,我发现它使用了交集类型,但行为不符合我的预期。

我想使用Object.assign将一些更改与旧对象合并以创建一个新对象(这是JS在遵循不可变数据模式时的常见做法)并让TypeScript验证部件和结果是否正确,但似乎TypeScript允许任何事情没有错误。

例如:

interface Thing {
    name: string;
    age: number;
    fav: boolean;
}

let oldThing: Thing = {
    name: "Aaa",
    age: 123,
    fav: false
};

let newThing: Thing = Object.assign({}, oldThing, {
    name: "Bbb",
    age: "abc", // should be type error
    fake: "fakey" // should be unknown prop error
});

Here it is in the playground.

为什么Object.assign允许对Thing进行错误分配?有没有办法使这项工作接近我的预期?

2 个答案:

答案 0 :(得分:4)

您在此直观地预期错误的原因是为Object.assign的返回值构造的交集类型是荒谬的,并且不能被任何实际值占用。但是,TypeScript无法验证这一点。此处Object.assign的返回值输入如下:

{
    name: string,
    age: string & number,
    fav: boolean,
    fake: string
}

当然没有string & number的实际值,但编译器并不知道。它很乐意构造这个荒谬的类型,然后当你尝试将它分配给Thing时,验证返回值中相应属性是否满足Thing中每个属性的类型。由于情况属实(每个nameagefav都存在,并至少满足Thing中所需的接口),因此分配成功。

如果您允许推断newThing类型,那么尝试为age属性分配任何内容,您就会发现问题:

let newThing = Object.assign({}, oldThing, {
    name: "Bbb",
    age: "abc",
    fake: "fakey"
});
newThing.age = 10;   // Compiler error because 10 is not a string
newThing.age = "10"; // Compiler error because "10" is not a number

答案 1 :(得分:0)

您可以通过添加< Thing>来强制检查TypeScript。在前面:

unzip