You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:24:22