Skip to content

Instantly share code, notes, and snippets.

@catwell
Created August 28, 2019 12:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save catwell/bda607d7c31a517d1683bb61c1692383 to your computer and use it in GitHub Desktop.
Save catwell/bda607d7c31a517d1683bb61c1692383 to your computer and use it in GitHub Desktop.
TypeScript - Type Guard for Discriminated Unions with Extract
export interface Chunky {
kind: 'chunky';
/* ... */
}
export interface Bacon {
kind: 'bacon';
/* ... */
}
export type Stuff = Chunky | Bacon;
type StuffKind = Stuff['kind'];
export function stuffIs<T extends StuffKind>(kind: StuffKind, stuff: Stuff): stuff is Extract<Stuff, {kind: T}> {
return stuff.kind === kind;
}
const chunky : Chunky = {kind: 'chunky'};
const bacon : Bacon = {kind: 'bacon'};
console.log(
stuffIs('chunky', chunky), /* true */
stuffIs('chunky', bacon), /* false */
stuffIs('bacon', chunky), /* false */
stuffIs('bacon', bacon), /* true */
);
@mikecann
Copy link

This can be further refined into a point free style like:

export const isKind = <
  TKindable extends {
    kind: string;
  },
  TKind extends TKindable["kind"]
>(
  kind: TKind
) => (item: TKindable): item is Extract<TKindable, { kind: TKind }> => item.kind == kind;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment