Skip to content

Latest commit

 

History

History
116 lines (92 loc) · 4.1 KB

0002-ban-typescript-enum.md

File metadata and controls

116 lines (92 loc) · 4.1 KB

Ban TypeScript Enum syntax

  • Status: accepted
  • Deciders: Joris MASSON
  • Date: 2021-04-13

Technical Story: request #20917 Ban TypeScript Enums syntax

Context and Problem Statement

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 ?

Alternatives to Enums

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

Considered Options

  • Ban Enums syntax usage
  • Status quo: Keep allowing Enums syntax usage

Pros and Cons of the Options

Ban 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.

Status quo: Keep allowing Enums syntax usage

  • 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.

Links