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

如何用TypeScript实现支持多参数组合的文档/对象获取函数?

问题2:实现类型安全的getObjects函数

类型定义(修正语法错误后)

type PersonDoc = { personId: string; age: number }
type ProjectDoc = { projectId: string; title: string }
type OrganizationDoc = { organizationId: string; name: string }

需求

实现getObjects函数:

  • 接收personId、projectId、organizationId的任意组合作为参数
  • 返回包含对应类型对象的结果,示例:
    • getObjects({ personId: "abc" }) → {person: {personId: "abc", age: 35}}
    • getObjects({ personId: "abc", projectId: "def" }) → 包含PersonDoc和ProjectDoc的对象
    • getObjects({ projectId: "def", organizationId: "qrs" }) → 包含ProjectDoc和OrganizationDoc的对象

解决方案

通过TypeScript映射类型实现参数与返回值的类型联动:

// 定义ID字段到文档类型和结果键的映射
type IdToDocMap = {
  organizationId: { key: 'organization'; type: OrganizationDoc };
  personId: { key: 'person'; type: PersonDoc };
  projectId: { key: 'project'; type: ProjectDoc };
};

// 参数类型:任意ID字段的可选组合
type GetObjectsParams = Partial<{ [K in keyof IdToDocMap]: string }>;

// 返回类型:根据传入的ID字段自动生成对应文档的键值对
type GetObjectsResult<T extends GetObjectsParams> = {
  [K in keyof T as T[K] extends string ? IdToDocMap[K]['key'] : never]: IdToDocMap[Extract<K, keyof IdToDocMap>]['type'];
};

function getObjects<T extends GetObjectsParams>(params: T): GetObjectsResult<T> {
  const result: any = {};

  // 生成组织文档(模拟数据,实际可替换为数据库查询)
  if (params.organizationId) {
    result.organization = {
      organizationId: params.organizationId,
      name: `组织-${params.organizationId}`
    } as OrganizationDoc;
  }

  // 生成人员文档
  if (params.personId) {
    result.person = {
      personId: params.personId,
      age: 35
    } as PersonDoc;
  }

  // 生成项目文档
  if (params.projectId) {
    result.project = {
      projectId: params.projectId,
      title: `项目-${params.projectId}`
    } as ProjectDoc;
  }

  return result as GetObjectsResult<T>;
}

使用示例

// 仅传入personId
const res1 = getObjects({ personId: "abc" });
// res1类型:{ person: PersonDoc },值为 { person: { personId: "abc", age: 35 } }

// 传入personId和projectId
const res2 = getObjects({ personId: "abc", projectId: "def" });
// res2类型:{ person: PersonDoc; project: ProjectDoc }

// 传入projectId和organizationId
const res3 = getObjects({ projectId: "def", organizationId: "qrs" });
// res3类型:{ project: ProjectDoc; organization: OrganizationDoc }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:15:53