Last active
March 20, 2022 22:57
-
-
Save LevPewPew/50a53190ac0123f649e9d1caac702573 to your computer and use it in GitHub Desktop.
KeysUnion custom utility type. create a union of strings out of keys in an interface where the value type match the given generic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// create union out of properties in an interface who'se value type match then given value types (can be given a union of types to match) #codesnippet | |
// Stack Overflow explanation https://stackoverflow.com/questions/54520676/in-typescript-how-to-get-the-keys-of-an-object-type-whose-values-are-of-a-given/66144780 | |
export type KeysUnion<T, V> = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T]; | |
// Playground | |
interface Cool { | |
ice: string; | |
cold: string; | |
} | |
interface Foobar { | |
fizz: string; | |
buzz: Cool; | |
} | |
interface FoobarWithNumbers { | |
fizz: string; | |
buzz: Cool; | |
apples: number; | |
} | |
const obj: Foobar = { | |
fizz: "test", | |
buzz: { | |
ice: "top", | |
cold: "kek" | |
} | |
} | |
const objWithApples: FoobarWithNumbers ={ | |
fizz: "test", | |
buzz: { | |
ice: "top", | |
cold: "kek" | |
}, | |
apples: 5 | |
} | |
// should error | |
function someFunction0(someObj: Foobar, key: string) { | |
return someObj[key]; | |
} | |
function someFunction1(someObj: Foobar, key: KeysUnion<Foobar, string>) { | |
return someObj[key]; | |
} | |
// FIXME ideally this would error since there is no number value present in Foobar | |
function someFunction2(someObj: Foobar, key: KeysUnion<Foobar, number>) { | |
return someObj[key]; | |
} | |
function someFunction2p1(someObj: Foobar, key: KeysUnion<FoobarWithNumbers, number>) { | |
return objWithApples[key]; | |
} | |
function someFunction3(someObj: Foobar, key: KeysUnion<Foobar, any>) { | |
return someObj[key]; | |
} | |
const x = someFunction1(obj, "fizz") | |
// should error | |
const y = someFunction1(obj, "nope") | |
// should error | |
const z = someFunction2(obj, "fizz") | |
const apples1 = someFunction2p1(objWithApples, "apples") | |
// should error | |
const fizz = someFunction2p1(objWithApples, "fizz") | |
// should error | |
const a = someFunction3(obj, "nope") | |
const b = someFunction3(obj, "fizz") | |
const c = someFunction3(obj, "buzz") | |
const explicitKey0: KeysUnion<Foobar, string> = "fizz" | |
// should fail | |
const explicitKey1: KeysUnion<Foobar, number> = "fizz" | |
// should fail | |
const explicitKey2: KeysUnion<Foobar, string> = "nope" | |
const explicitKey2p1: KeysUnion<FoobarWithNumbers, number> = "apples" | |
// should fail | |
const explicitKey3: KeysUnion<Foobar, string> = "buzz" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment