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

TypeScript中基于实体数组实现getModel方法参数自动补全的需求

解决方案

我们可以通过类型推导、方法重载和运行时映射的结合,实现getModel方法的参数自动补全,同时支持实体构造函数和字符串两种参数类型:

type AnyParamConstructor<T> = new (...args: unknown[]) => T;

class EntityA {}
class EntityB {}
class ModelA {}
class ModelB {}

// 提取构造函数的名称类型
type ClassName<T extends AnyParamConstructor<any>> = T["name"];

// 定义实体与对应Model的运行时映射,同时让TypeScript推导类型
const ENTITY_TO_MODEL_MAP = {
  [EntityA.name]: ModelA,
  [EntityB.name]: ModelB,
} as const;

// 从映射中提取类型,用于类型推导
type EntityToModel = typeof ENTITY_TO_MODEL_MAP;

class Modeler<T extends AnyParamConstructor<any>> {
  // 运行时存储实体名称到实体构造函数的映射
  private entityNameMap: Record<string, T> = {};

  constructor(private entities: T[]) {
    // 初始化名称到实体的映射
    entities.forEach(entity => {
      this.entityNameMap[entity.name] = entity;
    });
  }

  // 方法重载1:接收实体构造函数参数,自动补全EntityA/EntityB
  public getModel<K extends T>(entity: K): EntityToModel[ClassName<K>];
  // 方法重载2:接收实体名称字符串参数,自动补全"EntityA"/"EntityB"
  public getModel<K extends keyof EntityToModel>(entityName: K): EntityToModel[K];
  // 方法实现逻辑
  public getModel(arg: T | keyof EntityToModel) {
    // 判断参数类型,获取对应的实体名称
    const targetName = typeof arg === "string" ? arg : arg.name;
    // 返回对应的Model构造函数
    return ENTITY_TO_MODEL_MAP[targetName as keyof EntityToModel];
  }
}

const modeler = new Modeler([EntityA, EntityB]);
const modelA = modeler.getModel(EntityA); // 自动补全实体,返回ModelA类型
const modelAFromString = modeler.getModel("EntityA"); // 自动补全字符串,返回ModelA类型
const modelB = modeler.getModel(EntityB); // 返回ModelB类型
const modelBFromString = modeler.getModel("EntityB"); // 返回ModelB类型

核心实现要点:

  1. 类型推导:

    • 用ClassName<T>提取类的名称类型,让TypeScript能将实体构造函数和其名称字符串关联起来。
    • 通过as const标记ENTITY_TO_MODEL_MAP,让TypeScript保留具体的键值对类型,从而实现字符串参数的自动补全。
  2. 方法重载:

    • 两个重载分别处理实体构造函数和字符串参数,确保两种参数都能获得IDE自动补全,同时返回正确的Model类型。
  3. 运行时映射:

    • entityNameMap在构造函数初始化时建立实体名称到实体的映射,后续若需扩展实体实例相关逻辑可直接复用。
    • ENTITY_TO_MODEL_MAP存储实体名称到Model的映射,实现运行时的快速查找。
  4. 泛型约束:

    • Modeler<T extends AnyParamConstructor<any>>约束传入的实体必须是构造函数类型,确保类型安全。

内容的提问来源于stack exchange,提问作者Kleywalker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:03:08