TypeScript如何实现小写类名与对应类实例的映射类型声明
解决方案
要实现“小写类名到对应类实例”的精确类型映射,核心是让TypeScript保留数组中每个类的具体类型信息,而非将数组视为联合类型数组。以下是具体实现步骤:
将类数组声明为只读元组
用as const断言把数组转为只读元组,让TypeScript记住每个类的独立类型,避免合并为联合类型:class A { aProp: string = "A的属性"; } class B { bProp: number = 123; } // as const 保留数组中每个类的具体类型 const arr = [A, B] as const;定义精确的映射工具类型
创建一个工具类型,遍历元组中的每个类,将类名转为小写作为键,对应类的实例类型作为值:type InstanceMap<T extends readonly (new () => any)[]> = { [K in T[number] as `${Uncapitalize<K['name']>}`]: InstanceType<K>; };为instances指定类型
用上述工具类型声明instances,同时在赋值时添加类型断言确保类型安全:const instances: InstanceMap<typeof arr> = {} as InstanceMap<typeof arr>; arr.forEach((Class) => { instances[uncapitalize(Class.name) as keyof typeof instances] = new Class(); }); function uncapitalize<T extends string>(str: T): Uncapitalize<T> { return (str.charAt(0).toLowerCase() + str.slice(1)) as Uncapitalize<T>; }
原写法失效原因
你之前的类型[K in typeof arr[number]['name'] as ${Uncapitalize]: InstanceType<typeof arr[number]>存在两个关键问题:
typeof arr[number]是所有类的联合类型,导致每个键对应的实例类型是所有类实例的联合类型,而非当前类的专属实例。- 未保留数组中每个类的独立类型信息,TypeScript无法建立“类名”与“对应实例”的一对一关联。
验证效果
现在instances会被精确推断为:
{ a: A; b: B; }
访问instances.a时会自动提示aProp,访问instances.b时提示bProp,且无法将A实例赋值给b字段,反之亦然,完全符合类型安全要求。
内容的提问来源于stack exchange,提问作者Procyon
相关产品推荐
相关产品推荐

