如何在TypeScript中为键是类、值为对应类实例的Map添加类型标注?
核心逻辑
要实现这个场景的类型标注,核心是先明确TypeScript中「类构造函数」的类型表达,再关联构造函数和对应实例的类型关系,以下是不同场景的可选方案:
方案1:固定已知类的标注
如果你的Map只会存储提前确定的几个类(比如示例中的A、B),可以直接用联合类型标注:
class A {}; class B {}; // 键为A/B的构造函数,值为对应类的实例 const map: Map<typeof A | typeof B, A | B> = new Map(); map.set(A, new A()); // 类型校验通过 map.set(B, new B()); // 类型校验通过 // 错误用法会被TS直接拦截 // map.set(A, new B()); // 报错:不能将类型B分配给类型A | B
方案2:通用扩展标注(推荐)
如果需要Map支持存储任意类,且保证构造函数和实例类型严格对应,还能自动推导get返回值类型,可以用内置工具类型+泛型封装实现:
// 先定义构造函数通用类型 type Constructor<T = any> = new (...args: any[]) => T; class A {}; class B {}; // Map的键为任意构造函数,值为对应构造函数的实例类型 const map = new Map<Constructor, InstanceType<Constructor>>(); // 封装get方法实现自动类型推导,无需额外类型断言 function getInstance<T extends Constructor>(cls: T): InstanceType<T> { return map.get(cls) as InstanceType<T>; } // 使用示例 map.set(A, new A()); map.set(B, new B()); const a = getInstance(A); // TS自动推导a的类型为A const b = getInstance(B); // TS自动推导b的类型为B
方案3:无断言的强类型标注
如果你提前明确所有要存入Map的类的映射关系,可以直接定义映射类型,全程无类型断言,类型安全性最高:
class A {}; class B {}; // 定义类与实例的映射关系 type ClassInstanceMap = { [typeof A]: A, [typeof B]: B } const map = new Map<keyof ClassInstanceMap, ClassInstanceMap[keyof ClassInstanceMap]>(); map.set(A, new A()); // 校验通过 map.set(B, new B()); // 校验通过
内容的提问来源于stack exchange,提问作者Leonardo Raele
相关产品推荐
相关产品推荐

