54 lines
1.6 KiB
Plaintext
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]
|