如何在DefinitelyTyped库中正确声明符合提交规范的enum类型?
问题根因
运行时报错的核心原因是普通enum不是纯类型结构:
- 普通枚举会被TypeScript编译为真实存在的JS对象,需要运行时有对应的实现代码
- 你只提供了
@types/enum-test的类型定义文件,没有发布对应的enum-test真实JS包,所以运行时导入自然会提示找不到模块 - 你去掉
enumAttribute属性或者使用const enum时,TS会直接把枚举值内联到编译后的代码中,不会保留对enum-test模块的引用,因此不会触发运行时报错,但DefinitelyTyped的规范禁止使用const enum,所以该方案不可行。
符合DefinitelyTyped规范的解决方案
方案1:用字符串字面量联合类型替代枚举(最推荐)
这是DT仓库中绝大多数类型包处理可枚举值的标准做法,完全是纯类型,不会产生任何运行时依赖:
// index.d.ts (in node_modules/@types/enum-test) export type EnumType = "TYPEA" | "TYPEB" export interface SomeInterface { stringAttribute: string; enumAttribute?: EnumType; }
如果需要给用户提供和原生枚举一致的、可以直接引用的常量值,可以额外声明常量对象:
export declare const EnumType: { readonly TYPE_A: "TYPEA"; readonly TYPE_B: "TYPEB"; }
该写法的使用体验和普通枚举完全一致,同时完全符合DT的lint规范,也不会产生运行时依赖要求。
方案2:和真实JS包实现对齐
如果你定义的enum-test本身是有真实JS实现的NPM包,只需要保证类型定义和JS实现对齐即可:
- 在
.d.ts文件的枚举定义前加declare关键字,明确标识这是对已有JS实现的类型声明:
// index.d.ts export declare enum EnumType { TYPE_A = "TYPEA", TYPE_B = "TYPEB" }
- 要求使用方同时安装
enum-test真实JS包和@types/enum-test类型包即可,该情况也符合DT规范。
内容的提问来源于stack exchange,提问作者Tomas Schier
相关产品推荐
相关产品推荐

