You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript如何实现小写类名与对应类实例的映射类型声明

解决方案

要实现“小写类名到对应类实例”的精确类型映射,核心是让TypeScript保留数组中每个类的具体类型信息,而非将数组视为联合类型数组。以下是具体实现步骤:

  1. 将类数组声明为只读元组
    用as const断言把数组转为只读元组,让TypeScript记住每个类的独立类型,避免合并为联合类型:

    class A {
      aProp: string = "A的属性";
    }
    class B {
      bProp: number = 123;
    }
    
    // as const 保留数组中每个类的具体类型
    const arr = [A, B] as const;
    
  2. 定义精确的映射工具类型
    创建一个工具类型,遍历元组中的每个类,将类名转为小写作为键,对应类的实例类型作为值:

    type InstanceMap<T extends readonly (new () => any)[]> = {
      [K in T[number] as `${Uncapitalize<K['name']>}`]: InstanceType<K>;
    };
    
  3. 为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:52:31