TypeScript数组转带智能提示对象:键重映射类型报错求助
解决TypeScript数组映射类型中的键重映射错误
问题根源
你遇到的错误Type 'key' cannot be used to index type 'A[E]',本质是因为keyof A作用于数组类型时,返回的是数组所有属性的联合类型——除了数字索引,还包含length、push、pop等数组内置方法/属性。这些非数字索引对应的类型(比如number、() => void)并不是ListEntry,自然无法访问key属性。
解决方案
1. 过滤数组的非数字索引
在映射类型中,用Exclude<keyof A, keyof Array<any>>过滤掉数组的内置属性,只保留数字索引:
type MapListEntryArrayToRecord<A extends readonly ListEntry[]> = { [E in Exclude<keyof A, keyof Array<any>> as A[E]['key']]: A[E]['prop']; };
2. 保留键的字面量类型(实现智能提示)
普通的ListEntry[]类型会把key推断为string,无法生成具体键的智能提示。需要用as const断言把输入数组转为只读元组,保留每个key的字面量类型:
const input = [ { key: 'key1', prop: 'Prop1' }, { key: 'key2', prop: 'Prop2' }, ] as const;
3. 调整函数泛型约束
将函数泛型约束为readonly ListEntry[],适配只读元组类型:
function someFunction<const List extends readonly ListEntry[]>(list: List): MapListEntryArrayToRecord<List> { const ret = {} as MapListEntryArrayToRecord<List>; for (const { key, prop } of list) { ret[key as keyof typeof ret] = prop; } return ret; }
完整修改后的代码
interface ListEntry { key: string; prop: string; } type MapListEntryArrayToRecord<A extends readonly ListEntry[]> = { [E in Exclude<keyof A, keyof Array<any>> as A[E]['key']]: A[E]['prop']; }; const input = [ { key: 'key1', prop: 'Prop1' }, { key: 'key2', prop: 'Prop2' }, ] as const; function someFunction<const List extends readonly ListEntry[]>(list: List): MapListEntryArrayToRecord<List> { const ret = {} as MapListEntryArrayToRecord<List>; for (const { key, prop } of list) { ret[key as keyof typeof ret] = prop; } return ret; } const mapped = someFunction(input); // 现在可以获得key1、key2的智能提示 mapped.key1; // 类型为"Prop1" mapped.key2; // 类型为"Prop2"
内容的提问来源于stack exchange,提问作者hasezoey
相关产品推荐
相关产品推荐

