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

如何让TypeScript创建查找对象的泛型函数支持自定义键并保留类型检查

增强TypeScript查找函数的通用性

你可以通过扩展泛型参数并新增键名参数,实现支持指定任意合法键的通用查找函数,同时保留严格的类型检查。以下是修改后的实现:

通用版函数代码

function createLookup<K extends PropertyKey, T extends Record<K, PropertyKey>>(
  source: T[],
  key: K
) {
  return Object.fromEntries(source.map(el => [el[key], el])) as Record<T[K], T>;
}

泛型参数说明

  • K extends PropertyKey:约束传入的键名必须是合法的对象键类型(string、number、symbol)。
  • T extends Record<K, PropertyKey>:确保输入数组中的每个对象都包含指定的K键,且该键对应的值是可作为对象索引的合法类型(保证能成为查找对象的键)。
  • 返回类型Record<T[K], T>:明确查找对象的键类型为原对象中K字段的类型,值类型为原对象类型,让TypeScript能精准推断返回值的结构。

使用示例

示例1:使用数字类型键id

const users = [
  { id: 1, name: "Alice", age: 30 },
  { id: 2, name: "Bob", age: 25 }
];

const userLookup = createLookup(users, "id");
// 类型推断结果:Record<number, { id: number; name: string; age: number }>
console.log(userLookup[1]); // 输出:{ id: 1, name: "Alice", age: 30 }

示例2:使用字符串类型键slug

const posts = [
  { slug: "typescript-guide", title: "TS入门指南" },
  { slug: "react-best-practices", title: "React最佳实践" }
];

const postLookup = createLookup(posts, "slug");
// 类型推断结果:Record<string, { slug: string; title: string }>
console.log(postLookup["typescript-guide"]); // 输出:{ slug: "typescript-guide", title: "TS入门指南" }

类型检查效果

函数会自动拦截不合法的输入:

  • 当数组对象缺少指定键时:
    const invalidItems = [{ name: "Test" }];
    createLookup(invalidItems, "id"); // TypeScript报错:类型"{ name: string; }"不满足"Record<"id", PropertyKey>"约束
    
  • 当指定键对应的值不是合法索引类型时:
    const invalidValueItems = [{ id: { value: 1 } }];
    createLookup(invalidValueItems, "id"); // TypeScript报错:类型"{ value: number; }"无法赋值给PropertyKey类型
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:37:37