如何定义TypeScript函数返回类型,提取数组对象Slug作为明确键
问题
现有以下TypeScript代码:
interface Item { slug: string; description: string; } interface Params { id: number; items: Item[]; } function test(params: Params) { const result = {}; for (const item of params.items) { result[item.slug] = "Hello"; } return result; } const data = { id: 3, items: [ { slug: "one", description: "This is one" }, { slug: "two", description: "This is two" }, { slug: "three", description: "This is three" }, ] } const final = test(data)
调用test(data)后,返回对象的键是items数组中各对象的slug值,值为字符串。但当前final的类型是Record<string, string>,希望让final的类型明确为:
{ one: string; two: string; three: string; }
即从传入的items中提取具体的slug值生成精确的对象类型,该如何定义test函数的返回类型?
解决方案
要实现这个需求,需要结合泛型和字面量类型推断,让TypeScript捕获slug的具体值作为类型:
修改后的完整代码
function test<S extends string>(params: { id: number; items: { slug: S; description: string }[]; }) { // 断言result为目标类型,避免循环赋值时的类型报错 const result = {} as Record<S, string>; for (const item of params.items) { result[item.slug] = "Hello"; } return result; } const data = { id: 3, items: [ { slug: "one", description: "This is one" }, { slug: "two", description: "This is two" }, { slug: "three", description: "This is three" }, ] as const // 保留slug的字面量类型,避免被拓宽为string }; const final = test(data); // 此时final的类型自动推断为:{ one: string; two: string; three: string; }
核心说明
- 泛型
S extends string会自动捕获items中所有slug的字面量类型,形成联合类型"one" | "two" | "three"。 as const断言是关键:它让数组中的每个对象被推断为只读字面量类型,确保slug的值不会被TypeScript自动拓宽为宽泛的string类型。- 用
as Record<S, string>断言result,是因为初始化空对象{}的类型是{},需要明确告诉TypeScript它最终会变成键为S的对象,避免循环赋值时的类型错误。
内容的提问来源于stack exchange,提问作者Nik
相关产品推荐
相关产品推荐

