TypeScript自动列类型定义问题:数组键回调参数为any类型
TypeScript数组键列类型定义问题修复
我写了一段自动为列定义类型的TS代码,无需手动指定类型,但处理数组类型的键时出现问题:高亮render键时显示的类型正确,但实际回调函数中的value参数类型却为any。相关代码如下:
type Payload = { name: string; items: string[]; }; type Render<P> = (value: P) => any; type Col< T extends object, K = keyof T | Array<keyof T> > = K extends Array<keyof T> ? { key: K; render: Render<{ [key in K[number]]: T[key] }> } : K extends keyof T ? { key: K; render: Render<T[K]> } : never const cols: Col<Payload>[] = [ { key: 'name', render: (name) => name }, { key: ['name', 'items'], render: (obj) => `${obj.name} - ${obj.items.length}` }, ];
问题原因
原Col类型的默认泛型参数K = keyof T | Array<keyof T>是联合类型,TypeScript无法对数组类型的K进行正确的分布式条件类型推导。当处理数组键分支时,K没有被窄化到具体的数组元素集合,导致Render的泛型参数无法正确推断,最终回调参数类型退化为any。
修复方案
将Col拆分为单个键和数组键的具体类型,再合并为联合类型,让TypeScript能针对每个分支单独做类型检查:
type Payload = { name: string; items: string[]; }; type Render<P> = (value: P) => any; // 单个键对应的列类型 type SingleCol<T, K extends keyof T> = { key: K; render: Render<T[K]>; }; // 数组键对应的列类型 type MultiCol<T, K extends Array<keyof T>> = { key: K; render: Render<{ [Key in K[number]]: T[Key] }>; }; // 合并所有可能的列类型 type Col<T> = | SingleCol<T, keyof T> | MultiCol<T, Array<keyof T>>; const cols: Col<Payload>[] = [ { key: 'name', render: (name) => name // name类型自动推断为string }, { key: ['name', 'items'], render: (obj) => `${obj.name} - ${obj.items.length}` // obj类型自动推断为{name: string; items: string[]} }, ];
修复说明
- 拆分类型后,TypeScript会对联合类型的每个成员单独进行类型匹配
- 定义
cols时,每个列对象会被精准匹配到SingleCol或MultiCol分支,回调参数的类型就能被正确推断出来
内容的提问来源于stack exchange,提问作者Said Benmoumen
相关产品推荐
相关产品推荐

