下面有两个函数,mergeObj 函数使用interface定义, copyFields使用泛型定义;使用泛型定义的可以能正常提示出错误,而mergeObj不行;如果要使用interface 实现下面泛型的功能,要如何修改?
// 需要
// 泛型,多个类型参数互联约束
// target类型要包含 source的类型
interface Source {
}
interface Target extends Source {
}
function mergeObj(target:Target, source:Source): Target {
for (let key in source){
target[key]=(source)[key];
}
return target;
}
let obj={a:1, b:2};
let obj2={c:4};
console.log(mergeObj(obj, obj2)); // 没有报错提示
function copyFields<T extends U, U>(target: T, source: U): T {
for (let id in source) {
target[id] = (<T>source)[id];
}
return target;
}
let x = { a: 1, b: 2 };
copyFields(x, { c: 10 });
没有泛型约束时,
Target
和Source
之间没有明确的约束,传入的参数都是{ }
的子类型,子类型作为输入参数没有问题。泛型约束中,说明了
T
和U
的关系是继承(子类型)关系 (T extends U
),显然{ a, b }
并不是{ a }
的子类型。