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

如何用TypeScript泛型将const对象数组映射为类型元组?

解决TypeScript中基于const断言数组转换元组类型的泛型问题

需求场景

通过as const断言给JSON结构数组添加强类型:

const myList = [
  { type: 'uint256'},
  { type: 'address'}
] as const;

需要将其转换为对应元组类型[number, string],转换规则:

  • 当元素的type为"address"时,对应元组位置类型为string
  • 当元素的type为"uint256"时,对应元组位置类型为number
    最终要实现如下类型约束:
const foo: ConvertToTuple<typeof myList> = [1, 'asdf'];

原代码的问题

原泛型实现存在两处关键问题:

type ConvertToTuple<
  DataObjects extends readonly { type: "address" | "uint256" }[]
> = DataObjects extends readonly [infer CurrentObject, ...infer RestObjects]
  ? CurrentObject["type"] extends "address"
    ? [string, ...ConvertToTuple<RestObjects>]
    : CurrentObject["type"] extends "uint256"
    ? [number, ...ConvertToTuple<RestObject>] // 拼写错误:RestObject应为RestObjects
    : never
  : [];

抛出的错误原因:

  1. Type '"type"' cannot be used to index type 'CurrentObject':infer CurrentObject时未添加类型约束,TypeScript无法确定该类型存在type属性
  2. Type 'RestObjects' does not satisfy the constraint...:infer RestObjects同样无类型约束,TS默认推断为unknown[],不满足泛型参数的数组约束

修正后的泛型实现

我们需要在infer阶段为推断的类型添加明确约束,同时优化类型映射逻辑:

// 定义类型映射表,让转换规则更直观
type TypeMap = {
  uint256: number;
  address: string;
};

type ConvertToTuple<T extends readonly { type: keyof TypeMap }[]> = 
  T extends readonly [
    infer Head extends { type: keyof TypeMap }, 
    ...infer Tail extends readonly { type: keyof TypeMap }[]
  ]
    ? [TypeMap[Head['type']], ...ConvertToTuple<Tail>]
    : [];

验证效果

使用修正后的泛型,可正确完成类型转换:

const myList = [
  { type: 'uint256'},
  { type: 'address'}
] as const;

// 类型被正确推断为 [number, string]
const foo: ConvertToTuple<typeof myList> = [1, 'asdf']; 

// 类型不匹配时会触发TS报错(符合预期)
// const bar: ConvertToTuple<typeof myList> = ['1', 'asdf'];

关键优化点

  1. 抽离类型映射表:把type字符串与目标类型的对应关系单独定义为TypeMap,后续扩展新类型时只需修改该映射表
  2. 给infer添加约束:在推断元组头部和剩余元素时,明确约束它们的结构类型,解决索引访问和泛型约束不满足的问题
  3. 递归拼接元组:通过递归逻辑逐个处理元组元素,将每个元素的type映射为目标类型,最终拼接成符合要求的元组类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:35:51