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

TypeScript如何定义成员类型匹配对象属性类型的泛型数组?

解决思路与代码修正

一、修正Cells类型与getCells函数

你的核心需求是让Cells<Row>成为一个元组,每个元素的value类型对应Row属性的类型(第一个元素value是number,第二个是string)。原代码的问题在于Cells<T>的定义错误,且函数类型参数未正确使用。以下是修正后的代码:

interface Row {
  first: number;
  second: string;
}

// 提取T的属性键并保持声明顺序,生成键的元组
type Keys<T> = keyof T extends infer K ? K extends string ? [K, ...Keys<Omit<T, K>>] : never : never;
// 定义Cells为对应属性值类型的元组,每个元素是{ value: 对应类型 }
type Cells<T> = { [I in keyof Keys<T>]: { value: T[Keys<T>[I]] } };

const r: Row = {
  first: 1,
  second: "Hi"
};

console.log(r);

// 函数参数使用泛型T,返回Cells<T>类型
function getCells<T extends Record<string, unknown>>(r: T): Cells<T> {
  // 通过类型断言让TS识别返回结果为对应元组类型
  return Object.values(r).map(v => ({ value: v })) as Cells<T>;
}

// 调用时TS会自动推断泛型,无需显式传入
const cells = getCells(r);
// 此时cells[0].value为number类型,cells[1].value为string类型
console.log(cells);

关键说明:

  • Keys<T>:递归提取对象的属性键并保持声明顺序,生成键的元组(比如Keys<Row>是['first', 'second'])。
  • Cells<T>:通过映射键元组的每个索引位置,将对应属性值类型作为value的类型,最终生成符合需求的元组类型。
  • getCells函数:使用泛型T接收输入对象,返回Cells<T>;由于Object.values返回的是数组而非元组,需要用as Cells<T>做类型断言让TS识别顺序。

二、TypeScript中Array-like对象的用法

Array-like对象指的是拥有length属性且可通过数字索引访问元素,但不是Array实例的对象,比如arguments、DOM中的NodeList、HTMLCollection等。

1. 定义Array-like类型

在TypeScript中,有两种常见方式定义Array-like类型:

  • 只读场景直接用readonly T[]:
    type StringArrayLike = readonly string[];
    
  • 手动定义包含length和数字索引的接口:
    interface NumberArrayLike {
      length: number;
      [index: number]: number;
    }
    

2. 转换为真正的数组

Array-like对象没有Array的内置方法(如map、filter),通常需要先转换成数组:

  • 使用Array.from():
    const nodeList: NodeList = document.querySelectorAll('div');
    const divArray: HTMLElement[] = Array.from(nodeList);
    
  • 使用扩展运算符...:
    const argsArray: any[] = [...arguments];
    

3. 示例:处理Array-like参数

function sum(arrLike: { length: number; [index: number]: number }): number {
  let total = 0;
  for (let i = 0; i < arrLike.length; i++) {
    total += arrLike[i];
  }
  return total;
}

// 传入自定义Array-like对象
console.log(sum({ length: 3, 0: 1, 1: 2, 2: 3 })); // 输出6

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:23:17