54 lines
1.6 KiB
Plaintext

== Why is this an issue?
TypeScript allows all sorts of expressions to initialize enum members. However, as enums create their own scope, using identifiers can lead to unexpected results. The recommendation is thus to use only literal values when defining enum members.
=== What is the potential impact?
An enum member will shadow any variable defined with the same name in an enclosing scope. In the code example below, the `day` member value should derive from the `hour` const variable. But it is computed using the enum `hour` member instead, leading to the result 24 instead of the expected 1440.
[source,javascript]
----
const hour = 3600; // hour in seconds
enum DurationInMinutes {
hour = 60, // hour in minutes
day = 24 * hour / 60 // Expecting hour in seconds but got hour in minutes
}
----
== How to fix it
The recommended approach for enums is to initialize members with literals. Not only are literals easier to read, but they also avoid unexpected results due to the enum scope.
=== Code examples
==== Noncompliant code example
[source,javascript,diff-id=1,diff-type=noncompliant]
----
const hello = 'Hello';
enum Foo {
STRING = hello, // Variable
OBJECT = { hello }.hello.length, // Object
TEMPLATE = `${hello}, World`, // Template literal
SET = new Set([hello, 'world']).size, // Constructor
NUMBER = hello.length + 1, // Expression
}
----
==== Compliant solution
[source,javascript,diff-id=1,diff-type=compliant]
----
enum Foo {
STRING = 'Hello',
NUMBER = 0,
}
----
== Resources
=== Documentation
* TypeScript Documentation - https://www.typescriptlang.org/docs/handbook/enums.html#handbook-content[Enums]