Last active
March 10, 2023 20:36
-
-
Save zachhardesty7/63e56cd69e55a659120ec1e95a380a1e to your computer and use it in GitHub Desktop.
TS: KeysAssignableType
This file contains 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
// copyright 2023 Zach Hardesty | |
// want to check this out in the TypeScript playground? | |
// visit the following link to automatically see the latest version! | |
// https://www.typescriptlang.org/play?jsx=0#gist/63e56cd69e55a659120ec1e95a380a1e | |
/** | |
* Extracts keys of `TObj` that correspond to values that some type in the union | |
* `TTypes` can be assigned to | |
* | |
* @template TObj Object to extract keys from | |
* @template TTypes Type to check for assignability | |
* @returns Union of keys of `TObj` that correspond to values that `TTypes` can be | |
* assigned to | |
*/ | |
type KeysAssignableType<TObj, TTypes> = { | |
[P in keyof Required<TObj>]: TTypes extends Required<TObj>[P] ? P : never | |
}[keyof TObj] | |
type KeysAssignableExactType<TObj, TTypes> = { | |
[P in keyof Required<TObj>]: [TTypes] extends [Required<TObj>[P]] ? P : never | |
}[keyof TObj] | |
interface ITestObj1 { | |
a: string | |
b: number | |
c?: string | |
d?: number | |
e: boolean | |
f: string | number | |
g: undefined | |
h: null | |
i?: never | |
j: unknown | |
k: any | |
l: { a: string } | |
m: "a" | "b" | |
} | |
type T0_0 = Expect<KeysAssignableType<ITestObj1, string>, "a" | "c" | "f" | "j" | "k"> | |
type T1_0 = Expect< | |
KeysAssignableType<ITestObj1, string | number>, | |
"a" | "b" | "c" | "d" | "f" | "j" | "k" | |
// REVIEW: more appropriate stricter type? | |
// "f" | "j" | "k" | |
> | |
type T2_0 = Expect<KeysAssignableType<ITestObj1, any>, keyof ITestObj1> | |
type T3_0 = Expect<KeysAssignableType<ITestObj1, object>, "j" | "k"> | |
type T4_0 = Expect<KeysAssignableType<{}, any>, never> | |
type T5_0 = Expect< | |
KeysAssignableType<ITestObj1, { a: string; b: number }>, | |
"j" | "k" | "l" | |
> | |
type T6_0 = Expect< | |
KeysAssignableType<ITestObj1, "a">, | |
"a" | "c" | "f" | "j" | "k" | "m" | |
> | |
type T7_0 = Expect< | |
KeysAssignableType<ITestObj1, "a" | "b" | "c">, | |
"a" | "c" | "f" | "j" | "k" | "m" | |
// REVIEW: more appropriate stricter type? | |
// "a" | "c" | "f" | "j" | "k" | |
> | |
type T8_0 = Expect< | |
KeysAssignableType<ITestObj1, "a" | number>, | |
"a" | "b" | "c" | "d" | "f" | "j" | "k" | "m" | |
> | |
/** @see https://gist.github.com/zachhardesty7/1b5b6f6de328f1bb7c78cbe96ba5c720 */ | |
type Expect< | |
TInput extends TIntersect, | |
TExpected extends TIntersect, | |
TIntersect = TExpected & TInput, | |
> = TInput |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment