-
Notifications
You must be signed in to change notification settings - Fork 0
/
107.ts
133 lines (90 loc) · 2.26 KB
/
107.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// # Custom Utility types
// ---
// SLIDE
// ---
// ###
type Nullable<T> = T | null;
// ---
// SLIDE
// ---
// ###
/**
* `T | U` with all non matching properties set included as partial
*/
type InclusiveUnion<T, U> = (T | U) & Partial<T> & Partial<U>;
// ---
// SLIDE
// ---
// ###
/**
* Unwrap `Promise`
*/
type PromiseResult<T> = T extends PromiseLike<infer R> ? R : T;
/**
* Unwrap `Promise` of an async function's `ReturnType`.
*/
type AwaitReturnType<T extends (...args: any) => any> = PromiseResult<ReturnType<T>>;
// ---
// SLIDE
// ---
// ###
/**
* Recursive `Readonly<T>` wrapper.
*/
type Immutable<T> = T extends ImmutablePrimitive
? T
: T extends Array<infer U>
? ImmutableArray<U>
: T extends Map<infer K, infer V>
? ImmutableMap<K, V>
: T extends Set<infer M>
? ImmutableSet<M>
: ImmutableObject<T>;
type ImmutablePrimitive = undefined | null | boolean | string | number | symbol | bigint;
type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
// ---
// SLIDE
// ---
// ###
/**
* Get all keys of `T` that are type `Type`.
*
* Accepts optional, nullable and intersection types, but **not union** types.
* @example
* type ExampleType = {
* a: 'x';
* b: 'x' | null;
* c: 'x' | undefined;
* d?: 'x';
* e: 'x' & 'y';
* f: 'x' | 'y';
* };
* type ResultType = KeyOfType<ExampleType, 'x'>; // "a" | "b" | "c" | "d" | "e"
*/
declare type KeyOfType<T, Type> = {
[K in keyof T]: T[K] extends Type ? K : never
}[keyof T];
/**
* Get all keys of `T` that are assignable to `Type`.
*
* Accepts optional, nullable and union types, but **not intersection** types.
* @example
* type ExampleType = {
* a: 'x';
* b: 'x' | null;
* c: 'x' | undefined;
* d?: 'x';
* e: 'x' & 'y';
* f: 'x' | 'y';
* };
* type ResultType = KeyWithType<ExampleType, 'x'>; // "a" | "b" | "c" | "d" | "f"
*/
declare type KeyWithType<T, Type> = {
[K in keyof T]: Type extends T[K] ? K : never
}[keyof T];
// ---
// NEXT
// ---