Search code examples
typescripttypesdiscriminated-union

Type checking discriminated unions with adding new types


Lets say I have the following typescript types:

enum EntityKind {
  Foo = 'foo',
  Bar = 'bar',
}

type Foo = {
  kind: EntityKind.Foo,
  foo: string
}

type Bar = {
  kind: EntityKind.Bar,
  bar: number
}

type Entity = (Foo | Bar) & {
  id: string,
  name: string
}

What I want is to be able to have the type checker fail when I add a new type to my enum. So what I'm hoping for is:

enum EntityKind {
  Foo = 'foo',
  Bar = 'bar',
  Baz = 'baz',
}

and I would get some kind of error that would require me to define a new type Baz and add it to the union.

Is this possible?


Solution

  • If you want an error in the type Entity you could add another type to the intersection that requires EntityKind to extend EntityUnion['kind']:

    enum EntityKind {
      Foo = 'foo',
      Bar = 'bar',
    }
    
    type Foo = {
      kind: EntityKind.Foo,
      foo: string
    }
    
    type Bar = {
      kind: EntityKind.Bar,
      bar: number
    }
    type Check<T, U extends T> = {}
    
    type EntityUnion = Foo | Bar 
    type Entity = EntityUnion & {
      id: string,
      name: string
    } & Check<EntityUnion['kind'], EntityKind>