-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path5821-maptypes.ts
61 lines (55 loc) · 2.58 KB
/
5821-maptypes.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
/**
* 5821 - MapTypes
*
* Implement `MapTypes<T, R>` which will transform types in object T to different types defined by type R which has the following structure
*
* ```ts
* type StringToNumber = {
* mapFrom: string; // value of key which value is string
* mapTo: number; // will be transformed for number
* }
* ```
*
* ## Examples:
*
* ```ts
* type StringToNumber = { mapFrom: string; mapTo: number;}
* MapTypes<{iWillBeANumberOneDay: string}, StringToNumber> // gives { iWillBeANumberOneDay: number; }
* ```
*
* Be aware that user can provide a union of types:
* ```ts
* type StringToNumber = { mapFrom: string; mapTo: number;}
* type StringToDate = { mapFrom: string; mapTo: Date;}
* MapTypes<{iWillBeNumberOrDate: string}, StringToDate | StringToNumber> // gives { iWillBeNumberOrDate: number | Date; }
* ```
*
* If the type doesn't exist in our map, leave it as it was:
* ```ts
* type StringToNumber = { mapFrom: string; mapTo: number;}
* MapTypes<{iWillBeANumberOneDay: string, iWillStayTheSame: Function}, StringToNumber> // // gives { iWillBeANumberOneDay: number, iWillStayTheSame: Function }
* ```
*
*
*/
/* _____________ Your Code Here _____________ */
type Option<From = any, To = any> = { mapFrom: From, mapTo: To };
type MapTypes<T, R extends Option<any, any>> = {
[Key in keyof T]: (R extends Option<T[Key]> ? R['mapTo'] : never) extends infer Val
? [Val] extends [never]
? T[Key]
: Val
: never
}
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<MapTypes<{ stringToArray: string }, { mapFrom: string, mapTo: [] }>, { stringToArray: [] }>>,
Expect<Equal<MapTypes<{ stringToNumber: string }, { mapFrom: string, mapTo: number }>, { stringToNumber: number }>>,
Expect<Equal<MapTypes<{ stringToNumber: string, skipParsingMe: boolean }, { mapFrom: string, mapTo: number }>, { stringToNumber: number, skipParsingMe: boolean }>>,
Expect<Equal<MapTypes<{ date: string }, { mapFrom: string, mapTo: Date } | { mapFrom: string, mapTo: null }>, { date: null | Date }>>,
Expect<Equal<MapTypes<{ date: string }, { mapFrom: string, mapTo: Date | null }>, { date: null | Date }>>,
Expect<Equal<MapTypes<{ fields: Record<string, boolean> }, { mapFrom: Record<string, boolean>, mapTo: string[] }>, { fields: string[] }>>,
Expect<Equal<MapTypes<{ name: string }, { mapFrom: boolean, mapTo: never }>, { name: string }>>,
Expect<Equal<MapTypes<{ name: string, date: Date }, { mapFrom: string, mapTo: boolean } | { mapFrom: Date, mapTo: string }>, { name: boolean, date: string }>>,
]