问题描述
为什么将分配给对象文字的变量作为参数(let x = {color: 'red',width: 200}
)和传递对象文字作为参数({color: 'red',width: 200}
)之间有区别?
换句话说,参数的值是相同的({color: 'red',width: 200}
)。
那么,为什么编译器在传递对象时进行多余的检查,而在传递给该对象的变量传递时进行“常规形状”检查呢?
解决方法
考虑函数类型签名:
type SOME_OBJECT = {
propA: TYPE_A,propB: TYPE_B
}
function foo(obj: SOME_OBJECT) {
// WILL DO SOMETHING WITH obj
}
在上面的示例中,函数foo
期望对象obj
的类型为{{1}的propA
和类型为{{1的TYPE_A
}}。只要某些东西满足那些要求,函数propB
就可以完成它的工作。至少,这就是其合同所隐含的含义。那么,它的多余属性应该检查TYPE_B
参数吗?
现在让我们分配一个对象文字。假设您的类型具有可选参数 foo
。
obj
请注意,您已将maybe
属性拼写为interface SOME_OBJECT_WITH_OPTIONAL {
color: string,width: number,maybe?: boolean
}
const x1: SOME_OBJECT_WITH_OPTIONAL = {
color: "red",width: 200,mayeb: true // <--- TS ERROR HERE - EXCESS PROPERTY CHECKING IS REALLY IMPORTANT
}
。多亏了多余的属性检查,Typescript警告您您犯了该错误。如果不按原样处理,您能想象疼痛吗?在我们的示例中,没有属性会丢失,因为maybe
是可选的,因此允许其丢失。您将不会收到任何错误或警告。
期望mayeb
类型为maybe
的函数仍然不介意。因为存在所有必需的属性obj
和SOME_OBJECT_WITH_OBJECT
。
您可以在此处了解有关此主题的更多信息:
Typescrip Docs - Excess Property Checks
Medium - Introduction to TypeScript Interfaces — Object Literals and Function Types