转发安全
TypeScript中的类型兼容性基于结构子类型。
结构类型是一种仅根据其成员关联类型的方式。它正好与名义(nominal)类型造成对比。请看以下代码:函数
interface Named { name: string; } class Person { name: string; } let p: Named; // OK, because of structural typing p = new Person();
在使用基于名义类型的语言,好比C#或Java中,这段代码会报错,由于Person类没有明确说明其实现了Named接口。spa
TypeScript的结构性子类型是根据JavaScript代码的典型写法来设计的。 由于JavaScript里普遍地使用匿名对象,例如函数表达式和对象字面量,因此使用结构类型系统来描述这些类型比使用名义类型系统更好。设计
TypeScript的类型系统容许某些在编译阶段没法确认其安全性的操做。当一个类型系统具此属性时,被当作是“不可靠”的。TypeScript容许这种不可靠行为的发生是通过仔细考虑的。经过这篇文章,咱们会解释何时会发生这种状况和其有利的一面。code
TypeScript结构化类型系统的基本规则是,若是x要兼容y,那么y至少具备与x相同的属性。好比:对象
interface Named { name: string; } let x: Named; // y的推断类型 is { name: string; location: string; } let y = { name: 'Alice', location: 'Seattle' }; x = y;
这里要检查y是否能赋值给x,编译器检查x中的每一个属性,看是否能在y中也找到对应属性。 在这个例子中, y必须包含名字是name的string类型成员。y知足条件,所以赋值正确。blog
检查函数参数时使用相同的规则:递归
function greet(n: Named) { alert('Hello, ' + n.name); } greet(y); // OK
注意,y有个额外的location属性,但这不会引起错误。 只有目标类型(这里是 Named)的成员会被一一检查是否兼容。接口
这个比较过程是递归进行的,检查每一个成员及子成员。ip