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

TypeScript:如何在类型层面断言字符串为枚举有效值?

TypeScript枚举字符串推断问题解决方法

问题背景

定义了如下枚举:

enum MimeType {
  VideoMP4 = 'video/mp4',
  VideoQuicktime = 'video/quicktime',
}

同时有一个依赖枚举的泛型类型:

type Something<M extends MimeType> = {
  type: M;
  // 其他自定义结构
};

需求是实现一个泛型函数createSomething,从形如"前缀:枚举值"的输入字符串中,推断出对应的枚举类型,并返回Something<具体枚举成员>类型。

尝试的两种写法均存在问题:

  1. 第一种写法始终返回never,因为字符串字面量无法直接匹配枚举类型:
function createSomething<const V extends `${string}:${MimeType}`>(value: V): V extends `${string}:${infer M}` 
  ? M extends MimeType 
    ? Something<M>
    : never
  : never;

比如'video/mp4' extends MimeType结果为false,但'video/mp4' extends MimeType[keyof MimeType]结果为true,但后者无法满足Something的泛型约束。

  1. 第二种写法中,传入具体值时M会被推断为整个MimeType联合类型,无法得到具体枚举成员:
function createSomething<M extends MimeType, const V extends `${string}:${M}`>(value: V): Something<M>;

解决方案

方案1:通过Extract将字符串字面量映射为枚举类型

调整条件类型,先判断字符串是否属于枚举值集合,再用Extract提取对应的枚举成员:

// 类型定义
function createSomething<const V extends `${string}:${MimeType[keyof MimeType]}`>(
  value: V
): V extends `${string}:${infer M}`
  ? M extends MimeType[keyof MimeType]
    ? Something<Extract<MimeType, M>>
    : never
  : never;

// 实现逻辑
function createSomething(value: string) {
  const [, mimeTypeStr] = value.split(':');
  return { type: mimeTypeStr as MimeType };
}

测试验证:

const result = createSomething('demo:video/mp4');
// result 的类型为 Something<MimeType.VideoMP4>

方案2:调整泛型参数顺序优化推断

先推断具体的枚举值字符串,再关联到枚举类型:

// 类型定义
function createSomething<const MStr extends MimeType[keyof MimeType], const V extends `${string}:${MStr}`>(
  value: V
): Something<Extract<MimeType, MStr>>;

// 实现逻辑
function createSomething(value: string) {
  const [, mimeTypeStr] = value.split(':');
  return { type: mimeTypeStr as MimeType };
}

原理说明

  • TypeScript的枚举类型是成员标识符与成员值的联合类型,字符串字面量属于枚举值的集合(MimeType[keyof MimeType]),而非枚举类型本身。
  • Extract<MimeType, M>的作用是从MimeType枚举中筛选出值等于M的成员,将字符串字面量转换为对应的枚举类型,从而满足Something的泛型约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:37:46