UNPKG

1.31 kBTypeScriptView Raw
1import type {IfNever} from './if-never';
2
3/**
4Extract the keys from a type where the value type of the key extends the given `Condition`.
5
6Internally this is used for the `ConditionalPick` and `ConditionalExcept` types.
7
8@example
9```
10import type {ConditionalKeys} from 'type-fest';
11
12interface Example {
13 a: string;
14 b: string | number;
15 c?: string;
16 d: {};
17}
18
19type StringKeysOnly = ConditionalKeys<Example, string>;
20//=> 'a'
21```
22
23To support partial types, make sure your `Condition` is a union of undefined (for example, `string | undefined`) as demonstrated below.
24
25@example
26```
27import type {ConditionalKeys} from 'type-fest';
28
29type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
30//=> 'a' | 'c'
31```
32
33@category Object
34*/
35export type ConditionalKeys<Base, Condition> =
36{
37 // Map through all the keys of the given base type.
38 [Key in keyof Base]-?:
39 // Pick only keys with types extending the given `Condition` type.
40 Base[Key] extends Condition
41 // Retain this key
42 // If the value for the key extends never, only include it if `Condition` also extends never
43 ? IfNever<Base[Key], IfNever<Condition, Key, never>, Key>
44 // Discard this key since the condition fails.
45 : never;
46 // Convert the produced object into a union type of the keys which passed the conditional test.
47}[keyof Base];