先看代码:
let x = { a: 1 };
let y = { a: 1, b: 2 };
x = y; // OK
y = x; // Error
let xx = (a: number) => 0;
let yy = (a: number, b: number) => 0;
xx = yy; // Error
yy = xx; // OK
一开始看文档我很疑惑: 为什么对象允许携带额外属性赋值,而不允许缺少属性,而函数赋值则反之
结合实际使用场景我们很快就能发现这么做的好处,先讲函数,以Array.prototype.map
为例,其回调函数的签名为:
(value: any, index: number, array: any[]) => {}
而很多场景下,我们只需要用到回调函数的第一个参数,所以我们更期望是这样来调用:
[].map((value: any)=>{})
而不是每次都要带上多余的index与array参数。
更准确来讲,我们作为函数参数使用方,选择性使用传入的参数是安全的,所以函数赋值允许忽略额外参数。
而对象则不一样,我们作为对象提供方,赋值给其他类型,被赋值的类型可能在任何场合被我们不可控的计算过程所使用,如果缺少了必要的属性可能会出现不安全的取值。
2 条回复
[…] 刚接触Typescript那会儿有总结过不同类型之间相互赋值的情况:https://www.ccc5.cc/2702.html ,直到最近自己翻官方文档才知道有个更通俗的概念:逆变与协变。中文教程参考这个 […]
[…] 在此之前有过两篇不成熟的理解文章: * Typescript逆变与协变 * TypeScript类型兼容 […]