当我查看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
});
为什么Object.assign
允许对Thing
进行错误分配?有没有办法使这项工作接近我的预期?
答案 0 :(得分:4)
您在此直观地预期错误的原因是为Object.assign
的返回值构造的交集类型是荒谬的,并且不能被任何实际值占用。但是,TypeScript无法验证这一点。此处Object.assign
的返回值输入如下:
{
name: string,
age: string & number,
fav: boolean,
fake: string
}
当然没有string & number
的实际值,但编译器并不知道。它很乐意构造这个荒谬的类型,然后当你尝试将它分配给Thing
时,验证返回值中相应属性是否满足Thing
中每个属性的类型。由于情况属实(每个name
,age
和fav
都存在,并至少满足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