-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path28143-optionalundefined.ts
43 lines (39 loc) · 2.1 KB
/
28143-optionalundefined.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
/**
* 28143 - OptionalUndefined
*
* Implement the util type `OptionalUndefined<T, Props>` that turns all the properties of `T` that can be `undefined`, into optional properties. In addition, a second -optional- generic `Props` can be passed to restrict the properties that can be altered.
*
* ```ts
* OptionalUndefined<{ value: string | undefined, description: string }>
* // { value?: string | undefined; description: string }
*
* OptionalUndefined<{ value: string | undefined, description: string | undefined, author: string | undefined }, 'description' | 'author'>
* // { value: string | undefined; description?: string | undefined, author?: string | undefined }
* ```
*
*
*/
/* _____________ Your Code Here _____________ */
type OptionalUndefined<T, Props extends keyof T = keyof T> = {
[
Key in keyof T as Key extends Props
? undefined extends T[Key]
? Key
: never
: never
]?: T[Key]
} extends infer OptionalObj extends object
? Omit<Omit<T, keyof OptionalObj> & OptionalObj, never>
: never
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<OptionalUndefined<{ value: string | undefined }, 'value'>, { value?: string | undefined }>>,
Expect<Equal<OptionalUndefined<{ value: string, desc: string }, 'value'>, { value: string, desc: string }>>,
Expect<Equal<OptionalUndefined<{ value: string | undefined, desc: string }, 'value'>, { value?: string, desc: string }>>,
Expect<Equal<OptionalUndefined<{ value: string | undefined, desc: string | undefined }, 'value'>, { value?: string | undefined, desc: string | undefined }>>,
Expect<Equal<OptionalUndefined<{ value: string | undefined, desc: string }, 'value' | 'desc'>, { value?: string, desc: string }>>,
Expect<Equal<OptionalUndefined<{ value: string | undefined, desc: string | undefined }>, { value?: string, desc?: string }>>,
Expect<Equal<OptionalUndefined<{ value?: string }, 'value'>, { value?: string }>>,
Expect<Equal<OptionalUndefined<{ value?: string }>, { value?: string }>>,
]