Skip to main content

no-unsafe-enum-comparison

Disallow comparing an enum value with a non-enum value.

💡

此规则报告的一些问题可以通过编辑器 建议 手动修复。

💭

该规则需要 类型信息 才能运行,但这会带来性能方面的权衡。

在处理枚举时,TypeScript 编译器可能出奇地宽松。虽然枚举的明显安全问题是 在 TypeScript 5.0 中已解决,但一些逻辑陷阱仍然被允许。例如,允许将枚举值与非枚举值进行比较:

¥The TypeScript compiler can be surprisingly lenient when working with enums. While overt safety problems with enums were resolved in TypeScript 5.0, some logical pitfalls remain permitted. For example, it is allowed to compare enum values against non-enum values:

enum Vegetable {
Asparagus = 'asparagus',
}

declare const vegetable: Vegetable;

vegetable === 'asparagus'; // No error

上面的代码片段应该写成 vegetable === Vegetable.Asparagus。允许在比较中使用非枚举首先颠覆了使用枚举的意义。通过强制与正确类型的枚举进行比较:

¥The above code snippet should instead be written as vegetable === Vegetable.Asparagus. Allowing non-enums in comparisons subverts the point of using enums in the first place. By enforcing comparisons with properly typed enums:

  • 它使代码库对枚举成员更改值更具弹性。

    ¥It makes a codebase more resilient to enum members changing values.

  • 它允许代码 IDE 使用 "重命名符号" 功能快速重命名枚举。

    ¥It allows for code IDEs to use the "Rename Symbol" feature to quickly rename an enum.

  • 它将代码与正确的枚举语义对齐,即通过名称引用它们并将它们的值视为实现细节。

    ¥It aligns code to the proper enum semantics of referring to them by name and treating their values as implementation details.

eslint.config.mjs
export default tseslint.config({
rules: {
"@typescript-eslint/no-unsafe-enum-comparison": "error"
}
});

在线运行试试这个规则 ↗

示例

¥Examples

enum Fruit {
Apple,
}

declare let fruit: Fruit;

// bad - comparison between enum and explicit value instead of named enum member
fruit === 0;

enum Vegetable {
Asparagus = 'asparagus',
}

declare let vegetable: Vegetable;

// bad - comparison between enum and explicit value instead of named enum member
vegetable === 'asparagus';

declare let anyString: string;

// bad - comparison between enum and non-enum value
anyString === Vegetable.Asparagus;
Open in Playground

选项

该规则不可配置。

何时不使用它

¥When Not To Use It

如果你不介意枚举被视为命名空间值包,而不是不透明标识符,则可能不需要此规则。

¥If you don't mind enums being treated as a namespaced bag of values, rather than opaque identifiers, you likely don't need this rule.

有时,你可能希望从 API 或用户输入中提取值,然后在整个应用中将其用作枚举。在验证输入时,禁用该规则可能是合适的。或者,你可以考虑使用像 Zod 这样的验证库。有关此主题的进一步讨论,请参阅 #8557

¥Sometimes, you may want to ingest a value from an API or user input, then use it as an enum throughout your application. While validating the input, it may be appropriate to disable the rule. Alternately, you might consider making use of a validation library like Zod. See further discussion of this topic in #8557.

最后,在极少数情况下依赖仅作为 type 导入的第三方枚举,可能很难遵守此规则。你可以考虑在这些特定情况下使用 ESLint 禁用注释,而不是完全禁用此规则。

¥Finally, in the rare case of relying on an third party enums that are only imported as types, it may be difficult to adhere to this rule. You might consider using ESLint disable comments for those specific situations instead of completely disabling this rule.


Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.

See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.

'## 资源'