Skip to content

Instantly share code, notes, and snippets.

@frankpf
Created October 4, 2018 16:25
Show Gist options
  • Save frankpf/59128411625f0839e10af1918eed9efa to your computer and use it in GitHub Desktop.
Save frankpf/59128411625f0839e10af1918eed9efa to your computer and use it in GitHub Desktop.
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type DiscriminateUnion<Union, TagKey extends keyof Union, TagValue extends Union[TagKey]> =
Union extends Record<TagKey, TagValue> ? Union : never
type MatchingFunc<A extends { kind: string }, K extends A['kind'], U> = (a: Omit<DiscriminateUnion<A, 'kind', K>, 'kind'>) => U
function match<A extends { kind: string }>(discriminant: A) {
return <U>(obj:
{ [K in A['kind']]: MatchingFunc<A, K, U> } |
(Partial<{ [K in A['kind']]: MatchingFunc<A, K, U> }> & { default(): U }),
) => {
const objAny = obj as any
const caseFn = objAny[discriminant.kind]
return caseFn
? caseFn(discriminant) as U
: objAny.default()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment