1 | import type {NonRecursiveType, IsUnion} from './internal';
|
2 | import type {IsNever} from './is-never';
|
3 | import type {Simplify} from './simplify';
|
4 | import type {UnknownArray} from './unknown-array';
|
5 |
|
6 | /**
|
7 | Create a type with shared fields from a union of object types.
|
8 |
|
9 | Use-cases:
|
10 | - You want a safe object type where each key exists in the union object.
|
11 | - You want to focus on the common fields of the union type and don't want to have to care about the other fields.
|
12 |
|
13 | @example
|
14 | ```
|
15 | import type {SharedUnionFields} from 'type-fest';
|
16 |
|
17 | type Cat = {
|
18 | name: string;
|
19 | type: 'cat';
|
20 | catType: string;
|
21 | };
|
22 |
|
23 | type Dog = {
|
24 | name: string;
|
25 | type: 'dog';
|
26 | dogType: string;
|
27 | };
|
28 |
|
29 | function displayPetInfo(petInfo: Cat | Dog) {
|
30 | // typeof petInfo =>
|
31 | // {
|
32 | // name: string;
|
33 | // type: 'cat';
|
34 | // catType: string; // Needn't care about this field, because it's not a common pet info field.
|
35 | // } | {
|
36 | // name: string;
|
37 | // type: 'dog';
|
38 | // dogType: string; // Needn't care about this field, because it's not a common pet info field.
|
39 | // }
|
40 |
|
41 | // petInfo type is complex and have some needless fields
|
42 |
|
43 | console.log('name: ', petInfo.name);
|
44 | console.log('type: ', petInfo.type);
|
45 | }
|
46 |
|
47 | function displayPetInfo(petInfo: SharedUnionFields<Cat | Dog>) {
|
48 | // typeof petInfo =>
|
49 | // {
|
50 | // name: string;
|
51 | // type: 'cat' | 'dog';
|
52 | // }
|
53 |
|
54 | // petInfo type is simple and clear
|
55 |
|
56 | console.log('name: ', petInfo.name);
|
57 | console.log('type: ', petInfo.type);
|
58 | }
|
59 | ```
|
60 |
|
61 | @see SharedUnionFieldsDeep
|
62 |
|
63 | @category Object
|
64 | @category Union
|
65 | */
|
66 | export type SharedUnionFields<Union> =
|
67 | Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
|
68 | ? Exclude<Union, SkippedMembers> extends infer RelevantMembers
|
69 | ?
|
70 | | SkippedMembers
|
71 | | (IsNever<RelevantMembers> extends true
|
72 | ? never
|
73 | : Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
|
74 | : never
|
75 | : never;
|