在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本。 介绍TypeScript里的类型兼容性基于结构子类型的。 结构类型是只一种只使用其成员来描述类型的方式。 它正好与名义类型形成对比。 看下面的例子:
在使用名义类型的语言,比如C#或Java中,这段代码会报错,因为Person类没有明确说明其实现了Named接口。 TypeScript的结构性子类型是根据JavaScript代码的典型写法来设计的。 因为JavaScript里广泛地使用匿名对象,例如函数表达式和对象字面量,所以使用结构类型系统来描述这些类型比使用名义类型系统更好。 关于可靠性的注意事项TypeScript的类型系统允许一些在编译阶段无法否认其安全性的操作。当一个类型系统具此属性时,被当做是“不可靠”的。TypeScript允许这种不可靠行为的发生是经过仔细考虑的。通过这篇文章,我们会解释什么时候会发生这种情况和其有利的一面。 开始TypeScript结构化类型系统的基本规则是,如果
这里要检查 检查函数参数时使用相同的规则:
注意, 这个比较过程是递归进行的,检查每个成员及子成员。 比较两个函数比较原始类型和对象类型时是容易理解的,问题是如何判断两个函数是兼容的。 让我们以两个函数开始,它们仅有参数列表不同:
要查看 第二个赋值错误,因为 你可能会疑惑为什么允许
下面来看看如何处理返回值类型,创建两个仅是返回值类型不同的函数:
类型系统强制源函数的返回值类型必须是目标函数返回值类型的子类型。 函数参数双向协变当比较函数参数类型时,只有当源函数参数能够赋值给目标函数或者反过来时才能赋值成功。 这是不稳定的,因为调用者可能传入了一个具有更精确类型信息的函数,但是调用这个传入的函数的时候却使用了不是那么精确的类型信息。 实际上,这极少会发生错误,并且能够实现很多JavaScript里的常见模式。例如:
可选参数及剩余参数比较函数兼容性的时候,可选参数与必须参数是可交换的。 原类型上额外的可选参数并不会造成错误,目标类型的可选参数没有对应的参数也不是错误。 当一个函数有剩余参数时,它被当做无限个可选参数。 这对于类型系统来说是不稳定的,但从运行时的角度来看,可选参数一般来说是不强制的,因为对于大多数函数来说相当于传递了一些 有一个好的例子,常见的函数接收一个回调函数并用对于程序员来说是可预知的参数但对类型系统来说是不确定的参数来调用:
函数重载对于有重载的函数,源函数的每个重载都要在目标函数上找到对应的函数签名。 这确保了目标函数可以在所有源函数可调用的地方调用。 对于特殊的函数重载签名不会用来做兼容性检查。 枚举枚举类型与数字类型兼容,并且数字类型与枚举类型兼容。不同枚举类型之间是不兼容的。比如,
类类与对象字面量和接口差不多,但有一点不同:类有静态部分和实例部分的类型。 比较两个类类型的对象时,只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内。
类的私有成员私有成员会影响兼容性判断。 当类的实例用来检查兼容时,如果它包含一个私有成员,那么目标类型必须包含来自同一个类的这个私有成员。 这允许子类赋值给父类,但是不能赋值给其它有同样类型的类。 泛型因为TypeScript是结构性的类型系统,类型参数只影响使用其做为类型一部分的结果类型。比如,
上面代码里,
在这里,泛型类型在使用时就好比不是一个泛型类型。 对于没指定泛型类型的泛型参数时,会把所有泛型参数当成 比如,
高级主题子类型与赋值目前为止,我们使用了
语言里的不同地方分别使用了它们之中的机制。 实际上,类型兼容性是由赋值兼容性来控制的甚至在 |