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

TypeScript泛型自定义Enum写法冗余,求更简洁实现方案

简化TypeScript自定义泛型Enum的写法

我完全懂你这种重复写法的痛苦!每次写泛型Enum都要重复一遍类型,还要加个as交叉类型,真的很繁琐。这里有几个更简洁的方案,既能让IDE正确识别FolderVisibility.PUBLIC === 'public'这类类型判断,又能保留自定义Enum类的自有属性:

方案1:用工厂函数自动推断类型

首先假设你的自定义Enum类是类似这样的(带自有方法的版本):

class Enum<T extends Record<string, string | number>> {
  private readonly valuesMap: T;

  constructor(values: T) {
    this.valuesMap = Object.freeze({ ...values });
    // 将枚举键值对挂载到实例上
    Object.assign(this, values);
  }

  // 自定义方法:获取所有枚举值
  values(): Array<T[keyof T]> {
    return Object.values(this.valuesMap);
  }

  // 自定义方法:校验值是否为合法枚举值
  isValid(value: unknown): value is T[keyof T] {
    return this.values().includes(value as T[keyof T]);
  }
}

接下来我们写一个工厂函数,帮我们自动处理类型推断和交叉类型,不用手动重复代码:

function createEnum<T extends Record<string, string | number>>(values: T): Enum<T> & T {
  return new Enum(values) as Enum<T> & T;
}

现在创建枚举就变得非常简洁了,TypeScript会自动推断所有类型:

const FolderVisibility = createEnum({
  PUBLIC: 'public',
  PRIVATE: 'private'
});

此时IDE会正确识别FolderVisibility.PUBLIC的类型是'public',同时你也能正常调用Enum类的自有方法,比如FolderVisibility.values()或者FolderVisibility.isValid('public')。

方案2:优化Enum类的构造函数返回类型

如果你不想额外写工厂函数,也可以直接修改Enum类的构造函数,让它返回正确的交叉类型,这样创建实例时一步到位:

class Enum<T extends Record<string, string | number>> {
  private readonly valuesMap: T;

  constructor(values: T) {
    this.valuesMap = Object.freeze({ ...values });
    Object.assign(this, values);
    // 断言返回类型为Enum实例与枚举键值对的交叉类型
    return this as unknown as Enum<T> & T;
  }

  values(): Array<T[keyof T]> {
    return Object.values(this.valuesMap);
  }

  isValid(value: unknown): value is T[keyof T] {
    return this.values().includes(value as T[keyof T]);
  }
}

现在直接创建枚举即可,不需要任何额外的类型断言或重复泛型参数:

const FolderVisibility = new Enum({
  PUBLIC: 'public',
  PRIVATE: 'private'
});

两种方案都能实现你的需求:

  • 避免了重复的泛型参数和类型断言
  • IDE能精准识别每个枚举属性的具体值类型
  • 枚举参数通过Object.freeze保持只读状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:44:01