TypeScript如何一步实现接收字符串数组返回对应类型映射?
直接传入数组字面量实现类型安全的映射生成
问题背景
我有一个接收字符串数组作为参数的函数,返回以数组每个元素为键的映射,希望返回类型能准确体现这些键。当前实现如下:
function register<T extends string>(name: string, events: readonly T[]): { [S in T]: string } { const r = events.reduce((p, el) => { p[el] = `${name}:${el}`; return p; }, {} as { [S in T]: string }); return r; } const colors = ["blue", "green", "red", "yellow"] as const; const x = register<typeof colors[number]>('foo', colors) console.log(x.blue, x)
现在希望省去提前定义带as const断言的数组变量这一步,直接传入数组字面量完成调用,即实现:
const x = register<...?...>('foo', ["blue", "green", "red", "yellow"])
解决方案
有两种方式可以实现需求:
方式一:给数组字面量直接添加as const断言
无需修改函数,直接在传入的数组字面量后添加as const,让TypeScript捕获每个元素的具体字面量类型:
function register<T extends string>(name: string, events: readonly T[]): { [S in T]: string } { const r = events.reduce((p, el) => { p[el] = `${name}:${el}`; return p; }, {} as { [S in T]: string }); return r; } // 直接传入带as const的数组字面量 const x = register('foo', ["blue", "green", "red", "yellow"] as const); console.log(x.blue, x.green); // 类型提示正常,x的键严格对应数组元素
方式二:修改函数泛型,自动推断字面量元组
调整函数的泛型约束,让TypeScript默认将数组字面量推断为字面量元组,无需手动加as const:
function register<T extends readonly string[]>(name: string, events: T): { [S in T[number]]: string } { const r = events.reduce((p, el) => { p[el] = `${name}:${el}`; return p; }, {} as { [S in T[number]]: string }); return r; } // 直接传入数组字面量,自动推断类型 const x = register('foo', ["blue", "green", "red", "yellow"]); console.log(x.blue, x.red); // 类型提示正常
说明
- 方式一的核心是
as const断言,它会把数组标记为只读的字面量元组,让泛型T捕获每个元素的具体字符串值,从而生成准确的返回类型。 - 方式二通过将泛型参数改为约束
readonly string[],利用TypeScript的类型推断规则,自动把数组字面量推断为字面量元组,而非宽泛的string[],进而生成正确的映射类型。
内容的提问来源于stack exchange,提问作者max.ott
相关产品推荐
相关产品推荐

