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

TypeScript数组转对象泛型函数报错问题求助

泛型数组转对象函数的类型错误分析与修复

问题描述

尝试编写一个将数组转换为对象的泛型函数,代码如下:

type ObjType = { id: number; name: string; status: string };
const zzx: ObjType[] = [
  {
    id: 1,
    name: "A",
    status: "a"
  },
  {
    id: 2,
    name: "B",
    status: "b"
  },
  {
    id: 3,
    name: "C",
    status: "c"
  }
];

function arrayToObject<T>(
  arr: T[],
  key: string | number
): Record<string | number, T> {
  const result: Record<string, T> = {};
  for (const item of arr) {
    const value = item[key as keyof typeof T];
    result[value] = item;
  }
  return result;
}

const xx = arrayToObject<ObjType>(zzx, "id");

运行时出现错误:

Element implicitly has an 'any' type because expression of type 'string | number | symbol' can't be used to index type 'unknown'.
  No index signature with a parameter of type 'string' was found on type 'unknown'.

错误原因

  1. 泛型无约束导致类型推断失效:泛型T没有任何约束,TypeScript无法确定T包含哪些属性,只能将其视为unknown类型,自然无法通过key索引。
  2. key参数类型未与泛型关联:key被定义为string | number,但未限制为T的合法键,TypeScript无法确保传入的key是T中存在的属性。
  3. typeof T的错误用法:keyof typeof T是错误的写法——typeof操作符用于获取值的类型,而T本身就是类型,这里应该直接使用keyof T来表示T的所有键类型。
  4. 结果对象类型不匹配:result被声明为Record<string, T>,但返回类型是Record<string | number, T>,两者存在类型不一致的问题。

修复方案

给泛型T添加约束,同时将key参数的类型绑定为T的键类型,确保类型安全:

type ObjType = { id: number; name: string; status: string };
const zzx: ObjType[] = [
  { id: 1, name: "A", status: "a" },
  { id: 2, name: "B", status: "b" },
  { id: 3, name: "C", status: "c" }
];

// 泛型T约束为对象类型,K约束为T的键类型,且键对应的值可作为对象索引
function arrayToObject<T extends object, K extends keyof T>(
  arr: T[],
  key: K
): Record<T[K] extends PropertyKey ? T[K] : never, T> {
  const result: Record<PropertyKey, T> = {};
  for (const item of arr) {
    const value = item[key];
    result[value as PropertyKey] = item;
  }
  return result as Record<T[K] extends PropertyKey ? T[K] : never, T>;
}

// TypeScript可自动推断泛型,无需手动传入
const xx = arrayToObject(zzx, "id");
// xx的类型为Record<number, ObjType>,符合预期

关键改动说明

  • 新增泛型K并约束为keyof T,确保传入的key是T的合法属性。
  • 给T添加extends object约束,明确T是对象类型。
  • 返回类型根据T[K]的类型动态生成,确保结果对象的键类型与item[key]的类型一致。
  • 移除手动传入泛型的写法,TypeScript可通过参数自动推断类型,代码更简洁。

内容的提问来源于stack exchange,提问作者Deepak Negi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:25:23