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

如何从泛型对象数组推导对应类型的元组?

如何实现提取泛型对象数组中类型的元组类型?

需求描述

给定泛型参数T extends Array<SomeObjectWithGenericParameter<unknown>>,需要推导出一个元组类型,其中每个元素对应原数组中SomeObjectWithGenericParameter内部的泛型类型。

基础示例

type SomeObjectWithGenericParameter<T> = {
  value: T; 
}

// 待实现的类型
type ExtractDataAsArray<T extends Array<SomeObjectWithGenericParameter<unknown>>> = unknown;

type TypedArray = [a: string, b: number]; 
// 期望A等价于TypedArray
type A = ExtractDataAsArray<[{value: string}, {value: number}]>;

实际场景示例

type LoadingPayload<T> = {
  data:T, 
  isSuccess: true,
  isLoading: false, 
} | {
  data: null, 
  isSuccess: false, 
  isLoading: true, 
}

// 待实现的类型
type ExtractDataTypes<T extends Array<LoadingPayload<unknown>>> = unknown;

function myFunction<T extends Array<LoadingPayload<unknown>>> (dataPayloads: T, processData: (data: ExtractDataTypes<T>) => void) {}

const d1 : LoadingPayload<string> = {
  isLoading: true,
  isSuccess: false, 
  data: null, 
}; 

const d2 : LoadingPayload<number> = {
  isLoading: false, 
  isSuccess: true, 
  data: 2, 
}

myFunction([d1,d2], (data) => {
  const a: string = data[0]; // 期望data[0]为string类型
  const b: number = data[1]; // 期望data[1]为number类型
  const c: never = data[2]; // 期望data[2]为never类型
}); 

尝试的错误实现

以下实现未达到预期效果,示例中data被推断为Array<number>而非元组[string, number]:

type ExtractDataTypes<T extends Array<LoadingPayload<unknown>>> = {
  [K in keyof T ] : T[K] extends LoadingPayload<infer U> ? U : never; 
}

解决方案

问题出在泛型约束的类型上:使用Array<LoadingPayload<unknown>>作为约束时,TypeScript会将数组字面量宽泛地推断为数组类型(比如LoadingPayload<string | number>[]),而非保留元素具体类型的元组类型。我们需要调整约束,让TypeScript优先推断元组结构,再通过映射类型提取内部泛型。

正确实现代码

type LoadingPayload<T> = {
  data:T, 
  isSuccess: true,
  isLoading: false, 
} | {
  data: null, 
  isSuccess: false, 
  isLoading: true, 
}

// 修改约束为readonly LoadingPayload<unknown>[],保留元组结构
type ExtractDataTypes<T extends readonly LoadingPayload<unknown>[]> = {
  [K in keyof T]: T[K] extends LoadingPayload<infer U> ? U : never;
}

// 同步修改函数的泛型约束
function myFunction<T extends readonly LoadingPayload<unknown>[]>(dataPayloads: T, processData: (data: ExtractDataTypes<T>) => void) {}

const d1 : LoadingPayload<string> = {
  isLoading: true,
  isSuccess: false, 
  data: null, 
}; 

const d2 : LoadingPayload<number> = {
  isLoading: false, 
  isSuccess: true, 
  data: 2, 
}

myFunction([d1,d2], (data) => {
  const a: string = data[0]; // 正确推断为string
  const b: number = data[1]; // 正确推断为number
  const c: never = data[2]; // 正确推断为never
}); 

原理说明

  • 将泛型约束从Array<LoadingPayload<unknown>>改为readonly LoadingPayload<unknown>[],TypeScript会将传入的数组字面量推断为元组类型(比如[LoadingPayload<string>, LoadingPayload<number>]),而非合并类型的数组。
  • 映射类型{ [K in keyof T]: ... }作用于元组时,会逐个处理每个索引对应的元素类型,最终生成对应的元组结果,而非数组类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:42:41