我正在学习子类型,并且想知道为什么这里给出一个例子https://www.typescriptlang.org/docs/handbook/type-compatibility.html可以编译,但是当我将子类型直接作为参数传递给函数时,它不会编译。
这是来自 typescriptlang.org 的原始代码
interface Named {
name: string;
}
let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" };
function greet(n: Named) {
console.log("Hello, " + n.name);
}
greet(y); // OK
编译得很好。但是这个版本,子类型没有分配给 y,失败了。
interface Named {
name: string;
}
let x: Named;
function greet(n: Named) {
console.log("Hello, " + n.name);
}
greet({ name: "Alice", location: "Seattle" }); // NOT OK
我收到错误:
类型参数 '{ name: string;位置:字符串; }' 不可分配给“Named”类型的参数。对象文字只能指定已知属性,并且“Named”类型中不存在“location”。
为什么子类型 { name: "Alice", location: "Seattle" } 必须首先分配给一个变量?
这是因为当您在需要特定类型的地方使用“新鲜”对象文字(意味着尚未分配给变量的对象文字)时,它是often添加类型中未提及的属性时出错。所以这被标记为错误超额财产检查。这是少数几个将类型视为“封闭”或“精确”的地方之一(如微软/TypeScript#12936与“开放”相对。
如果您不想进行过多的财产检查,有一些解决方法。一种是添加一个索引签名的类型n
参数,以便所有额外的属性都是可接受的:
function greet(n: Named & { [x: string]: unknown }) {
console.log("Hello, " + n.name);
}
greet({ name: "Alice", location: "Seattle" }); // okay
或者,如果您通常想要进行此类检查但只想致电greet()
对于该特定对象文字,您可以使用类型断言避免中间变量:
greet({ name: "Alice", location: "Seattle" } as Named); // okay
由你决定。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)