为何TypeScript中类构造函数不兼容但实例却兼容?
为什么TypeScript中构造函数不兼容但实例兼容?
这本质是TypeScript结构类型系统的特性导致的,分两部分解释:
1. 构造函数不兼容的原因
typeof Person代表的是Person类的构造函数类型,它的签名是(name: string, age: number) => Person。而Employee的构造函数签名是(name: string, age: number, salary: number) => Employee。
函数类型的兼容性遵循参数逆变、返回值协变的规则:
- 当把一个函数赋值给另一个函数类型时,要求被赋值的函数能接收目标类型的所有调用参数。这里Person的构造函数只需要2个参数,但Employee的构造函数必须传3个参数,没法用调用Person构造的方式(传2个参数)去调用Employee的构造函数,所以类型不兼容。
2. 实例兼容的原因
TypeScript对类实例的类型检查是基于结构的,只要一个对象拥有目标类型的所有属性(且类型匹配),就认为它兼容目标类型。
- Employee的实例拥有
name: string、age: number,完全覆盖了Person实例的所有属性要求,额外的salary属性不影响兼容性。所以new Employee("", 0, 0)可以赋值给Person类型的变量。
简单总结:构造函数是函数类型,按函数的规则做兼容性检查;实例是对象类型,按结构匹配的规则检查,两者的判断逻辑不一样。
// 补充验证:给Employee构造函数的salary加默认值,让它能接收2个参数 class Employee { name: string; age: number; salary: number; constructor(name: string, age: number, salary: number = 0) { this.name = name; this.age = age; this.salary = salary; } } const pCtor: typeof Person = Employee; // 此时不会报错,构造函数兼容了
内容的提问来源于stack exchange,提问作者NeoZoom.lua
相关产品推荐
相关产品推荐

