- Status: accepted
- Deciders: Joris MASSON
- Date: 2021-04-13
Technical Story: request #20917 Ban TypeScript Enums syntax
Enums have been a part of TypeScript ever since we started adopting it in Tuleap development. Naturally, we started using them. There is a TC39 Proposal to add this syntax to the ECMAScript specification. However, at the time of writing this document, the proposal has not moved from stage zero since 2018. Enums might never be added to ECMAScript... Moreover, the TypeScript Documentation itself advises to "maybe hold off on using [Enums]". The question is then: Should we ban TypeScript Enums usage ?
Enums lead to more runtime code than alternatives. See for example this simple Enum with only two values:
enum Direction {
BEFORE = "before",
AFTER = "after",
}
const dir = Direction.BEFORE;
if (dir === Direction.BEFORE) {}
Compiles to:
var Direction;
(function (Direction) {
Direction["BEFORE"] = "before";
Direction["AFTER"] = "after";
})(Direction || (Direction = {}));
const dir = Direction.BEFORE;
if (dir === Direction.BEFORE) { }
See in TypeScript Playground
This Enum can completely be replaced by string constants and union types. It leads to less runtime code:
type Direction = "after" | "before";
const AFTER: Direction = "after";
const BEFORE: Direction = "before";
const dir = BEFORE;
if (dir === BEFORE) {}
Compiles to:
const AFTER = "after";
const BEFORE = "before";
const dir = BEFORE;
if (dir === BEFORE) { }
See in TypeScript Playground
Enums can also be replaced by plain old Object, which again leads to less runtime code. It is a bit more verbose than plain string constants though:
const Direction = {
BEFORE: "before",
AFTER: "after",
} as const;
type DirectionType = typeof Direction[keyof typeof Direction];
const dir = Direction.BEFORE;
if (dir === Direction.BEFORE) {}
Compiles to:
const Direction = {
BEFORE: "before",
AFTER: "after",
};
const dir = Direction.BEFORE;
if (dir === Direction.BEFORE) { }
See in TypeScript Playground
- Ban Enums syntax usage
- Status quo: Keep allowing Enums syntax usage
Using an eslint
rule, we are able to ban usage of Enums.
- Good, because alternatives produce fewer lines of runtime code.
- Good, because it avoids reliance on a TypeScript syntax that does not exist in JavaScript, as advised (see here and here) by the TypeScript handbook itself.
- Good, because Enums offer a straightforward syntax provided by the TypeScript language.
- Bad, because Enums lead to more runtime code than alternatives.
- Bad, because it makes our TypeScript code depend on language syntax that might never be available in JavaScript.