交集类型将多种类型组合为一种。这样,您便可以将现有类型加在一起,以获得具有所需所有功能的单个类型。
这是扩展功能
function extend<T extends object, U extends object>(first: T, second: U): T & U {
const result = <T & U>{};
for (let id in first) {
(<T>result)[id] = first[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<U>result)[id] = second[id];
}
}
return result;
}
const x = extend({ a: 'hello' }, { b: 42 });
变量result
被声明为类型T&U
。因此它应该在类型U
和类型T
上都具有两者属性,对吧?
当我们迭代类型T的属性时,为什么将result
声明为类型T
for (let id in first) {
// I'm confused about code below
(<T>result)[id] = first[id];
}
我认为不需要将result
设置为T类型,但出现了错误
for (let id in first) {
result[id] = first[id];
// error
//Type 'T[Extract<keyof T, string>]' is not assignable to type '(T & U)[Extract<keyof T, string>]'.
//Type 'T' is not assignable to type 'T & U'.
// Type 'object' is not assignable to type 'T & U'.
// Type 'object' is not assignable to type 'T'.
// 'object' is assignable to the constraint of type 'T', but 'T' could be instantiated with a
// different subtype of constraint 'object'.
}
有人可以解释该错误,并在错误发生时给出更具体的代码示例吗?
答案 0 :(得分:0)
问题是当您的两种类型T
和U
共享具有不同类型的属性名称时。考虑这种情况:
interface Button { state: 'OFF' | 'ON' }
interface Dial { state: 'OFF' | 1 | 2 | 3 }
let button = { state: 'ON' };
let dial = { state: 3 };
let obj = {} as Button & Dial;
// this property has type 'OFF', otherwise it can't be both a Button and a Dial
obj.state
// this is a type error because button.state isn't necessarily a valid Dial state
obj.state = button.state;
// this is a type error because dial.state isn't necessarily a valid Button state
obj.state = dial.state;
这不是技术性知识;通常,您的函数不是类型安全的,因为它并不总是返回有效的T
和有效的U
两者。编译器正确,在此处给出错误。如果您知道仅将使用共享属性一致(或没有共享属性)的类型调用函数,则只能使用类型断言来使错误静音。