TypeScript如何从实例类型访问类静态类型,是否存在InstanceType的反向工具?
从TypeScript实例类型访问类静态类型的实现方案
问题本质
TypeScript中类的实例类型仅包含实例侧成员定义,所有静态成员归属到typeof 类对应的构造函数类型下,两者是完全独立的类型体系,因此直接从实例类型上读取静态属性的写法天然无法生效。
此外TypeScript采用结构类型系统:两个结构完全一致的不同类的实例类型会被判定为等价,但两者的静态成员可能完全不同,因此语言没有内置与InstanceType反向的类型工具,无法直接从实例类型推导唯一对应的构造函数静态类型。
实现方案
轻量场景:手动关联
如果仅针对单个类使用,直接手动声明实例类型和对应构造函数的关联即可:
class YouCantAccessStaticTypeFromInstance { static example: boolean } type exampleInstance = YouCantAccessStaticTypeFromInstance // 手动关联实例类型对应的静态类型 type ExampleClassStaticType = typeof YouCantAccessStaticTypeFromInstance type x = ExampleClassStaticType['example'] // 类型为boolean,符合预期
通用场景:添加类型标记
如果需要通用的反向查询能力,可以通过类型层面的唯一标记给实例类型挂载对应的构造函数类型:
// 声明唯一符号作为类型标记,仅存在于类型层面,不会影响运行时代码 declare const StaticTypeMarker: unique symbol // 包装工具:给实例类型挂载对应构造函数的静态类型标记 type AttachStaticType<T extends new (...args: any[]) => any> = InstanceType<T> & { [StaticTypeMarker]: T } // 查询工具:从带标记的实例类型中提取对应的构造函数静态类型 type GetStaticType<T> = T extends { [StaticTypeMarker]: infer C extends new (...args: any[]) => any } ? C : never
使用方式如下:
class YouCantAccessStaticTypeFromInstance { static example: boolean } // 用包装工具得到带静态类型标记的实例类型 type exampleInstance = AttachStaticType<typeof YouCantAccessStaticTypeFromInstance> // 直接提取静态属性类型 type x = GetStaticType<exampleInstance>['example'] // 类型为boolean,符合预期
内容的提问来源于stack exchange,提问作者ThomasReggi
相关产品推荐
相关产品推荐

