Skip to content

Instantly share code, notes, and snippets.

@lumie1337
Last active December 12, 2018 18:34
Show Gist options
  • Save lumie1337/047bfd434e5fb20ddd025882fb621c16 to your computer and use it in GitHub Desktop.
Save lumie1337/047bfd434e5fb20ddd025882fb621c16 to your computer and use it in GitHub Desktop.
// how keyof works
type P1 = keyof ({ a: string } | { b: string }) // => "a" & "b" (aka never)
type P2 = keyof ({ a: string } & { b: string }) // => "a" | "b"
type P3 = ({ a: string } | { b: string }) extends infer P ? P extends object ? keyof P : never : never
// => "a" | "b"
// in P3, the conditional type forces branching so that expression keyof P is applied for each part of the union rather than the whole
// the reason why this works as it does:
// a function is given as argument { a: string } | { b: string }, then keyof cannot be statically determined
// infact at runtime, we cannot know what all the keys of { a: string } | { b: string } are, because we can
// always only inspect one case
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment