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

如何将泛型数组转为Record并保留各索引的字面量类型?

解决TypeScript数组转Record时字面量类型不匹配问题

先定义基础类型和常量:

type Person = {
  name: string;
  age: number;
};

const bob = {
  name: "Bob",
  age: 32,
} as const;

const alice = {
  name: "Alice",
  age: 43,
} as const;

需求是实现一个函数,接收Person对象数组,转换为以对象name属性为键、对象本身为值的Record类型,且每个键对应的值类型要精准匹配原始对象,而非联合类型。

单个对象的可行实现

处理单个对象时,泛型可以精准追踪对象的字面量类型:

function getPerson<T extends Person>(personOption: T) {
  let person = {} as Record<(typeof personOption)["name"], typeof personOption>;
  return person;
}

const person = getPerson(bob); // 类型为Record<"Bob", { readonly name: "Bob"; readonly age: 32; }>
const personName = person.Bob.name; // 类型为"Bob"

数组版本的问题

直接扩展为数组参数时,TypeScript会把数组元素类型合并为联合类型,导致返回的Record中每个键对应的值都是联合类型,无法精准匹配:

function getPeople<T extends Person>(peopleOptions: T[]) {
  let people = {} as Record<
    (typeof peopleOptions)[number]["name"],
    (typeof peopleOptions)[number]
  >;
  return people;
}

const people = getPeople([bob, alice]);

const bobName = people.Bob.name; // 类型为"Bob" | "Alice"(不符合预期)
const aliceName = people.Alice.name; // 类型为"Bob" | "Alice"(不符合预期)

解决方案

通过元组类型约束和映射类型,让TypeScript追踪数组中每个元素的具体类型,从而生成精准的Record类型:

function getPeople<T extends readonly Person[]>(peopleOptions: T) {
  // 构建精准的Record类型:用每个元素的name作为键,元素本身作为值
  type PeopleRecord = {
    [K in T[number] as K["name"]]: K;
  };

  const people = {} as PeopleRecord;

  // 补充运行时赋值逻辑,确保对象正确构建
  peopleOptions.forEach(person => {
    people[person.name as keyof PeopleRecord] = person;
  });

  return people;
}

// 调用时用as const保留数组的元组字面量类型
const people = getPeople([bob, alice] as const);

const bobName = people.Bob.name; // 类型为"Bob"(符合预期)
const aliceName = people.Alice.name; // 类型为"Alice"(符合预期)

核心要点

  • 将泛型T约束为readonly Person[],并在调用时添加as const,让TypeScript将数组识别为元组而非普通数组,保留每个元素的具体字面量类型。
  • 使用映射类型[K in T[number] as K["name"]]: K:遍历元组中的每个元素K,用K["name"]作为键名,K本身作为键值类型,实现键与值的精准对应。
  • 补充运行时的赋值逻辑,确保函数不仅类型正确,运行时也能生成预期的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 12:02:49