TypeScript中new () =>类型属性赋值报错原因及正确赋值方式
问题解答
1. 为什么构造函数传入FlossView无报错?
你的Foo类构造函数接受的参数类型是new () => BarView<Type>——本质是一个无参构造函数,返回BarView<Type>实例。而FlossView作为类,它的类型是typeof FlossView,对应签名是new () => FlossView(这里假设你的组件构造函数允许无参调用,或TypeScript做了宽松兼容)。
因为FlossView继承自BarView<Thing>,它的实例是BarView<Thing>的子类型。根据TypeScript对函数返回类型的协变规则,new () => FlossView可以安全赋值给new () => BarView<Thing>,所以构造函数传入FlossView完全合法。
2. 为什么foo.renderer = FlossView会报错?
从你的报错信息来看,TypeScript判定foo.renderer的类型是BarView<Thing> | undefined——这是实例类型,但你赋值的FlossView是构造函数类型(typeof FlossView),两种类型完全不兼容,因此报错。
出现这种差异的常见原因:
- 你可能不小心把
Foo类中renderer的类型标注写错了,比如写成了renderer?: BarView<Type>(实例类型)而非构造函数类型; - React.Component子类的构造函数默认需要接收props参数,你的
new () => BarView<Type>签名不符合实际构造函数,但TypeScript在构造函数传参时做了宽松检查,赋值时则严格校验了类型不匹配。
3. 如何获取FlossView的实例类型?
在TypeScript中,有两种简单方式获取类的实例类型:
- 直接使用类名:
FlossView本身就代表它的实例类型,比如let view: FlossView就表示view是FlossView的一个实例; - 使用内置工具类型
InstanceType:如果只有构造函数类型(比如typeof FlossView),可以用InstanceType<typeof FlossView>推导实例类型,结果和直接写FlossView完全等价。
示例代码:
// 方式1:直接用类名 let myView: FlossView; // 方式2:从构造函数类型推导 type FlossViewInstance = InstanceType<typeof FlossView>; let anotherView: FlossViewInstance; // 和myView类型一致
内容的提问来源于stack exchange,提问作者Isaa褋 Weisberg
相关产品推荐
相关产品推荐

