我很难理解,为什么将对象文字直接分配给变量(键入接口)失败,但是对完全相同的对象类型的间接分配进行检查。
考虑以下示例:
interface User { name: string }
// vs code complains: "only specify known properties"
const usr1 : User = {
name: 'John',
age: 42 // <- squiggly red line
}
// works
const usr2 : User = usr1;
usr1
和usr2
都被键入为User
,两者都接收相同的值。为什么Visual Studio代码只抱怨第一个?
是我不了解的IDE问题还是TypeScript概念?
考虑扩展示例:
interface User { name: string }
// doesn't work
// const usr1 : User = {
// name: 'John',
// age: 42 // <- squiggly red line
// }
// assignment works obviously because usr3 is not typed to User
const usr3 = {
name: 'Jane',
age: 33
}
// works
const usr2 : User = usr3;
const getName = (u: User) => console.log(u.name);
getName(usr2); // works!
getName({ name: 'Jane', age: 33 }); // doesn't work!
这令人困惑! u
的形式参数getName()
接收完全相同的值。第一次有效,第二次无效。
答案 0 :(得分:0)
对象文字在分配给其他变量或作为参数传递时会受到特殊对待,并进行多余的属性检查。如果对象文字具有“目标类型”所没有的任何属性,则会出现错误。
绕开这些检查实际上非常简单。最简单的方法是只使用类型断言:
let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
但是,如果您确定对象可以具有某些以特殊方式使用的额外属性,则更好的方法可能是添加字符串索引签名。如果SquareConfig可以具有上述类型的color和width属性,但是还可以具有许多其他属性,那么我们可以这样定义它:
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
在这里,我们说SquareConfig可以具有任意数量的属性,只要它们不是颜色或宽度,它们的类型就无关紧要。
解决这些检查的最后一种方法(可能有点令人惊讶)是将对象分配给另一个变量:由于squareOptions不会进行过多的属性检查,因此编译器不会给您错误。
>let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);
({https://www.typescriptlang.org/docs/handbook/interfaces.html,副标题为“多余的属性检查”)