TypeScript如何从函数嵌套数组参数推导返回对象的精确键类型
实现方案
你遇到的类型宽化问题可以通过泛型捕获字面量类型解决,完整代码如下:
TypeScript 5.0+ 最优写法(无需额外语法调用)
TS5.0 新增的const泛型参数可以自动捕获数组字面量的精确类型,无需用户调用时加额外断言:
export function trackKeys<const T extends string>( node: HTMLElement, { names }: { names: T[] } ): Record<T, (e: Event) => void> { const methods = names.reduce((obj, name) => { return { ...obj, [name]: (e: Event) => { // 原有业务逻辑 }, }; // 给reduce初始值加类型断言,避免类型推导报错 }, {} as Record<T, (e: Event) => void>); // 补充返回语句,原有代码未返回methods return methods; }
效果验证
调用时直接传入数组字面量即可自动推导精确返回类型:
const node = document.createElement('div'); const obj = trackKeys(node, { names: ["apple", "potato"] }); // obj 类型自动推导为:{ apple: (e: Event) => void; potato: (e: Event) => void }
低版本TS兼容写法(5.0以下)
如果使用低于5.0的TS版本,无法使用const泛型,修改写法如下:
export function trackKeys<T extends string>( node: HTMLElement, { names }: { names: readonly T[] } ): Record<T, (e: Event) => void> { const methods = names.reduce((obj, name) => { return { ...obj, [name]: (e: Event) => { // 原有业务逻辑 }, }; }, {} as Record<T, (e: Event) => void>); return methods; }
调用时需要加as const避免字面量被宽化为string:
const obj = trackKeys(node, { names: ["apple", "potato"] as const });
原代码问题说明
- 未使用泛型捕获
names数组的元素字面量类型,直接声明names: string[]会导致所有字符串值被宽化为通用string类型 - 未补充
return methods语句,函数默认返回void无法拿到结果对象
内容的提问来源于stack exchange,提问作者Chique
相关产品推荐
相关产品推荐

