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

TypeScript中简化类枚举对象类型定义的方法

TypeScript 实现类型安全伪枚举方案

直接使用as const断言+原生类型推导语法即可解决所有问题,无需重复定义类型和接口。

最终实现代码

// 仅需定义一次常量对象,无需提前声明接口/联合类型
const application = {
    ELECTRIC: {propA: true, propB: 11, propC: "eee"},
    HYDRAULIC: {propA: false, propB: 59, propC: "hhh"},
    PNEUMATIC: {propA: true, propB: 87, propC: "ppp"},
} as const;

// 自动推导枚举键联合类型:"ELECTRIC" | "HYDRAULIC" | "PNEUMATIC"
type Application = keyof typeof application;

// 自动推导枚举值联合类型:application.ELECTRIC | application.HYDRAULIC | application.PNEUMATIC
type ApplicationValue = typeof application[Application];

// 用法和原生JS完全一致
const foo = application.ELECTRIC;
let bar: ApplicationValue;
bar = application.HYDRAULIC; // 类型校验通过
// bar = {propA: true, propB: 1, propC: "invalid"} // 类型报错,严格限制为枚举内定义的值

对应问题逐一解决

1. 消除重复定义问题

  • 不需要提前编写Application联合类型、ApplicationProps接口,所有类型从常量对象自动推导,后续增删枚举成员时,类型会自动同步,不需要修改额外的类型代码。
  • 如果确实需要获取枚举值的公共属性结构,直接通过派生类型获取即可:type ApplicationProps = ApplicationValue,等价于之前手动写的接口定义。
  • 如果需要约束枚举值必须符合固定结构,避免写错属性名/类型,使用TS 4.9+支持的satisfies运算符即可,不会丢失类型推导:
    interface ApplicationProps {
      propA: boolean;
      propB: number;
      propC: string;
    }
    const application = {
        ELECTRIC: {propA: true, propB: 11, propC: "eee"},
        HYDRAULIC: {propA: false, propB: 59, propC: "hhh"},
        PNEUMATIC: {propA: true, propB: 87, propC: "ppp"},
    } satisfies Record<string, ApplicationProps>;
    

2. 精准约束bar的类型

  • 之前手动标注ApplicationProps的问题在于,它仅校验对象结构,任何符合{propA: boolean, propB: number, propC: string}的对象都能赋值给bar,无法严格限制为枚举内定义的成员。
  • 用ApplicationValue(即typeof application[keyof typeof application])做类型标注时,TS会严格校验赋值内容必须是application对象下定义的成员值,完全匹配伪枚举的约束需求。

3. 简化跨文件导入

  • 只需要在枚举定义文件导出常量和派生类型即可,不需要额外导出多余内容:
    // enums/application.ts
    export const application = { /* 枚举定义 */ } as const;
    export type Application = keyof typeof application;
    export type ApplicationValue = typeof application[Application];
    
  • 其他文件使用时,仅需引入一次常量和需要的类型即可,不需要重复编写长串类型提取语法:
    // 其他业务文件
    import { application, type ApplicationValue } from './enums/application';
    let bar: ApplicationValue;
    bar = application.HYDRAULIC;
    
    其中type前缀是TS 4.5+支持的类型导入标记,导入的内容仅在类型检查阶段生效,不会被打包到运行时代码中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:36:22