2

I would like dirVectors[Turn.Straight] to fail at compile-time.

enum Direction {
    Up,
    Down,
    Right,
    Left,
}

enum Turn {
    Clockwise,
    Counterclockwise,
    Straight,
}

const dirVectors = {
    [Direction.Up]: [0, 1],
    [Direction.Down]: [0, -1],
    [Direction.Right]: [1, 0],
    [Direction.Left]: [-1, 0]
} as Record<Direction, [number, number]>;

I'm assuming the reason dirVectors[Turn.Straight] is OK is because they're both numbers, with Straight = 2, which is a subset of Direction {0,...,3}. When I assign a unique string to each enum's value, it does fail at compile-time. However, is it possible to get the compile-time error without going the string route?

azizj
  • 3,428
  • 2
  • 25
  • 33
  • 1
    If two enum entries has the same value, they can be used interchangeably to index a `Record`. I don't think there's anyway to change that without assigning each enum entry a globally unique value. – Alex Wayne Sep 11 '20 at 18:04

1 Answers1

3

If you assign values to Enum, it works as expected:

enum Direction {
  Up = 'Up',
  Down = 'Down',
  Right = 'Right',
  Left = 'Left'
}

enum Turn {
  Clockwise = 'Clockwise',
  Counterclockwise = 'Counterclockwise',
  Straight = 'Straight'
}

const dirVectors = {
  [Direction.Up]: [0, 1],
  [Direction.Down]: [0, -1],
  [Direction.Right]: [1, 0],
  [Direction.Left]: [-1, 0]
} as Record<Direction, [number, number]>

dirVectors[Direction.Up] // compiles
dirVectors[Turn.Straight] // does not compile

Question is, do you really need Enum? Are you using anything from Enum which union types does not provide? See if following works for you:

type Direction = 'Up' | 'Down' | 'Right' | 'Left'

type Turn = 'Clockwise' | 'Counterclockwise' | 'Straight'

const dirVectors: Record<Direction, [number, number]> = {
  Up: [0, 1],
  Down: [0, -1],
  Right: [1, 0],
  Left: [-1, 0]
}

dirVectors['Down'] // compiles
dirVectors['Straight'] // does not compile
Pritam Kadam
  • 2,388
  • 8
  • 16
  • The question asked `However, is it possible to get the compile-time error without going the string route?` – teddybeard Sep 11 '20 at 17:16
  • Yes, included other approach! – Pritam Kadam Sep 11 '20 at 17:17
  • I always assumed enums were preferred over union types because of namespaces and just the universal prevalence of them in other languages. https://stackoverflow.com/questions/40275832/ goes into depth as to why that's not the case. I'll start using union types. Thanks! – azizj Sep 11 '20 at 18:35