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

TypeScript 如何将数组泛型转换为其元素值的联合类型

TypeScript 泛型工具类型 ValueOf 实现方案

需求说明

我们需要实现泛型工具类型ValueOf<T>,可将满足T extends string[]的数组泛型转换为其所有元素值组成的联合类型,适配业务场景代码,保证调用transform函数时可以正确推导返回值类型。

最终实现代码

// 核心ValueOf实现,T[number]直接获取数组元素的联合类型
type ValueOf<T extends readonly string[]> = T[number];

class Foo<T extends string> {
  public value: T;

  constructor(value: T) {
    this.value = value;
  }
}

// 泛型加const修饰符,让TS自动推导数组字面量类型,不需要手动加as const
function transform<const T extends string[]>(foo: Foo<string>, newAllowedValues: T): Foo<ValueOf<T>> {
  if (newAllowedValues.length === 0) {
    throw new Error('允许值列表不能为空');
  }

  if (newAllowedValues.indexOf(foo.value) === -1) {
    foo.value = newAllowedValues[0];
  }

  return foo as unknown as Foo<ValueOf<T>>;
}

let foo1 = new Foo<'a' | 'b'>('a');
// 自动推导foo2类型为 Foo<'b' | 'c'>,无需额外语法
let foo2 = transform(foo1, ['b', 'c']);

实现说明

  • 核心ValueOf<T>通过TypeScript内置的索引访问写法T[number]实现,该语法会自动遍历数组的所有数字索引,将对应位置的元素类型合并为联合类型,完全满足需求。
  • transform函数的泛型参数添加了const修饰符,这是TypeScript 5.0+的特性,会让编译器自动把传入的数组参数按字面量类型推导,不会拓宽为通用的string[],调用时不需要手动添加as const,适配高频调用的使用场景。

低版本TS兼容方案

如果使用的是TypeScript 5.0以下版本,去掉泛型的const修饰符,调用时给数组参数添加as const断言即可:

// 兼容TS <5.0的写法
function transform<T extends readonly string[]>(foo: Foo<string>, newAllowedValues: T): Foo<ValueOf<T>> {
  // 逻辑和上面实现完全一致
}
// 调用时加as const
let foo2 = transform(foo1, ['b', 'c'] as const);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:15:03