1. interface Todo {
    2. title: string;
    3. description: string;
    4. completed: boolean;
    5. }
    6. type MyPick<T, K extends keyof T> = {
    7. [P in K]: T[P];
    8. };
    9. type TodoPreview = MyPick<Todo, 'title' | 'completed'>;
    10. const todo: TodoPreview = {
    11. title: 'Clean room',
    12. completed: false,
    13. };
    1. interface Todo {
    2. title: string;
    3. description: string;
    4. }
    5. type MyReadonly<T> = {
    6. readonly [P in keyof T]: T[P];
    7. };
    8. const todo: MyReadonly<Todo> = {
    9. title: 'Hey',
    10. description: 'foobar',
    11. };
    12. todo.title = 'Hello'; // Error: cannot reassign a readonly property
    13. todo.description = 'barFoo'; // Error: cannot reassign a readonly property
    1. const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const;
    2. type TupleToObject<T extends readonly (string | number)[]> = {
    3. [X in T[number]]: X;
    4. };
    5. type result = TupleToObject<typeof tuple>; // expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
    1. type arr1 = ['a', 'b', 'c'];
    2. type arr2 = [3, 2, 1];
    3. type First<T extends any[]> = T[number] extends never ? never : T[0];
    4. // type First<T extends any[]> = T['length'] extends 0 ? never : T[0]
    5. type MyFirst<T extends unknown[]> = T extends [infer F, ...(infer R)] ? F : never;
    6. type head1 = First<arr1>; // expected to be 'a'
    7. type head2 = First<arr2>; // expected to be 3
    1. type tesla = ['tesla', 'model 3', 'model X', 'model Y'];
    2. type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'];
    3. type Length<T extends readonly any[]> = T['length'];
    4. type teslaLength = Length<tesla>; // expected 4
    5. type spaceXLength = Length<spaceX>; // expected 5
    1. type MyExclude<T, K> = T extends K ? never : T;
    2. type Result = MyExclude<'a' | 'b' | 'c', 'a'>; // 'b' | 'c'
    1. type ExampleType = Promise<string>
    2. type MyAwaited<T extends Promise<unknown>> = T extends Promise<infer X>
    3. ? X extends Promise<unknown>
    4. ? MyAwaited<X>
    5. : X
    6. : never;
    7. type Result = MyAwaited<ExampleType> // string
    1. type If<T extends boolean, A, B> = T extends true ? A : B;
    2. type A = If<true, 'a', 'b'>; // expected to be 'a'
    3. type B = If<false, 'a', 'b'>; // expected to be 'b'
    1. type Concat<T extends any[], K extends any[]> = T extends [...(infer A)]
    2. ? K extends [...(infer B)]
    3. ? [...A, ...B]
    4. : never
    5. : never;
    6. type Concat<T extends any[], K extends any[]> = [...T, ...K];
    7. type Result = Concat<[1, 3], [2, 5]>; // expected to be [1, 3, 2, 5]
    1. type IsEqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
    2. ? 1
    3. : 2
    4. ? true
    5. : false;
    6. type Includes<T extends readonly any[], U> = T extends [infer R, ...infer Rest]
    7. ? true extends IsEqual<R, U>
    8. ? true
    9. : Includes<Rest, U>
    10. : false;
    11. type isPillarMen = Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">; // expected to be `false`
    1. type Push<T extends any[], K> = [...T, K];
    2. type Result = Push<[1, 2], '3'>; // [1, 2, '3']
    1. type Unshift<T extends any[], K> = [K, ...T];
    2. type Result = Unshift<[1, 2], 0> // [0, 1, 2,]
    1. const foo = (arg1: string, arg2: number): void => {};
    2. type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer R) => unknown ? [...R] : never;
    3. type FunctionParamsType = MyParameters<typeof foo>; // [arg1: string, arg2: number]
    1. const fn = (v: boolean) => {
    2. if (v) return 1;
    3. else return 2;
    4. };
    5. type MyReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R
    6. ? R
    7. : never;
    8. type a = MyReturnType<typeof fn>; // should be "1 | 2"
    1. type Subsequence<T extends any[]> = T extends [infer F, ...(infer R)]
    2. ? [F, ...Subsequence<R>] | Subsequence<R>
    3. : [];
    4. type Subsequence<T extends any[], Prefix extends any[] = []> = T extends [infer F, ...(infer R)]
    5. ? Subsequence<R, Prefix | [...Prefix, F]>
    6. : Prefix;
    7. type A = Subsequence<[1, 2]>; // [] | [1] | [2] | [1, 2]
    1. type Combination<
    2. // [foo, bar, baz], the original T, this won't be changed
    3. T extends string[],
    4. // foo | bar | baz > bar | baz > baz > ... need this because T[number] is fixed
    5. Unioned extends string = T[number],
    6. // foo | bar | baz > foo > ... for `Unioned extends Permutated ? never : Unioned`
    7. Permutated extends string = Unioned
    8. > =
    9. | Unioned
    10. // full union: foo | bar | baz
    11. | (Permutated extends any
    12. ? // [Permutation](https://github.com/type-challenges/type-challenges/issues/614)
    13. // Permutation will stop when Unioned is never
    14. // Permutation will loop each value and apply to the following
    15. // split it: `foo Combination<bar | baz>`, `foo` and `bar | baz` are mutually exclusive
    16. `${Permutated}${Combination<
    17. T,
    18. Unioned extends Permutated ? never : Unioned
    19. >}`
    20. : never);
    21. type Keys = Combination<["foo", "bar", "baz"]>;
    1. type foo = {
    2. name: string;
    3. age: string;
    4. };
    5. type coo = {
    6. age: number;
    7. sex: string;
    8. };
    9. // type Merge<F, S> = {
    10. // [P in keyof F | keyof S]: P extends keyof S ? S[P] : P extends keyof F ? F[P] :never
    11. // }
    12. // type Merge<F, S> = {
    13. // [P in keyof (F & S)]: P extends keyof S ? S[P] : P extends keyof F ? F[P] :never
    14. // }
    15. type Merge<T, U> = Omit<Omit<T, keyof U> & U, never>;
    16. type Result = Merge<foo, coo>; // expected to be {name: string, age: number, sex: string}
    1. type NodeA = {
    2. type: "A";
    3. name: string;
    4. flag: number;
    5. };
    6. type NodeB = {
    7. type: "B";
    8. id: number;
    9. flag: number;
    10. };
    11. type NodeC = {
    12. type: "C";
    13. name: string;
    14. flag: number;
    15. };
    16. type Nodes = NodeA | NodeB | NodeC;
    17. type ReplacedNodes = ReplaceKeys<
    18. Nodes,
    19. "name" | "flag",
    20. { name: number; flag: string }
    21. >;
    22. // {type: 'A', name: number, flag: string} | {type: 'B', id: number, flag: string} | {type: 'C', name: number, flag: string} // would replace name from string to number, replace flag from number to string.
    23. type ReplacedNotExistKeys = ReplaceKeys<Nodes, "name", { aa: number }>;
    24. type ReplaceKeys<
    25. U,
    26. T extends PropertyKey,
    27. Y extends {
    28. [J in PropertyKey]: any;
    29. }
    30. > = U extends {}
    31. ? {
    32. [K in keyof U]: K extends keyof Y ? Y[K] : K extends T ? never : U[K];
    33. }
    34. : never;
    1. type Foo = {
    2. [key: string]: any;
    3. foo(): void;
    4. }
    5. type A = RemoveIndexSignature<Foo> // expected { foo(): void }
    6. type RemoveIndexSignature<T,K=keyof T> = {
    7. [K in keyof T as string extends K ? never
    8. : number extends K ? never
    9. : symbol extends K ? never
    10. : K]: T[K]
    11. }
    12. type RemoveIndexSignature<T, P=PropertyKey> = {
    13. [K in keyof T as P extends K ? never : K extends P ? K : never]: T[K]
    14. }
    1. type PString1 = "";
    2. type PString2 = "+85%";
    3. type PString3 = "-85%";
    4. type PString4 = "85%";
    5. type PString5 = "85";
    6. // type PercentageParser<
    7. // T extends string,
    8. // P extends string = '',
    9. // N extends string = '',
    10. // S extends string = ''> =
    11. // T extends `${infer A}${infer B}` ? A extends '+'|'-' ?
    12. // PercentageParser<B, A, N, S> : A extends '%' ?
    13. // PercentageParser<B, P, N, A> :
    14. // PercentageParser<B, P, `${N}${A}`, S> : [P, N, S];
    15. type Parser1<A extends string> = A extends `${infer H}${infer _}`
    16. ? H extends "-" | "+"
    17. ? H
    18. : ""
    19. : "";
    20. type Parser2<A extends string> = A extends `${infer _}%` ? "%" : "";
    21. type Parser3<A extends string> =
    22. A extends `${Parser1<A>}${infer M}${Parser2<A>}` ? M : "";
    23. type PercentageParser<A extends string> = [Parser1<A>, Parser3<A>, Parser2<A>];
    24. type R1 = PercentageParser<PString1>; // expected ['', '', '']
    25. type R2 = PercentageParser<PString2>; // expected ["+", "85", "%"]
    26. type R3 = PercentageParser<PString3>; // expected ["-", "85", "%"]
    27. type R4 = PercentageParser<PString4>; // expected ["", "85", "%"]
    28. type R5 = PercentageParser<PString5>; // expected ["", "85", ""]
    1. // 题28
    2. interface User {
    3. name: string;
    4. age: number;
    5. address: string;
    6. }
    7. // type PartialByKeys<T, U extends keyof T> = {
    8. // []
    9. // }
    10. // type PartialByKeys<
    11. // T,
    12. // K=keyof T,
    13. // PartialOne = {[J in K & keyof T]?: T[J]|undefined},
    14. // RequiredOne = {[J in Exclude<keyof T,K>]: T[J]},
    15. // Intersection = PartialOne&RequiredOne,
    16. // > =
    17. // {[J in keyof Intersection]: Intersection[J]} ;
    18. type PartialByKeys<T, U extends keyof T> = Merge<Partial<T>, Omit<T, U>>;
    19. type UserPartialName = PartialByKeys<User, "name">; // { name?:string; age:number; address:string }
    20. // 题29
    21. type OmitByType<T, K> = {
    22. [P in keyof T as T[P] extends K ? never : P]: T[P];
    23. };
    24. type OmitBoolean = OmitByType<
    25. {
    26. name: string;
    27. count: number;
    28. isReadonly: boolean;
    29. isEnable: boolean;
    30. },
    31. boolean
    32. >; // { name: string; count: number }
    33. // 题30
    34. // type Test = '123';
    35. // type StringToUnion<T> = T extends `${infer A}${infer R}` ? A | StringToUnion<R> : never;
    36. // type Result = StringToUnion<Test>; // expected to be "1" | "2" | "3"
    37. // 题31
    38. type GetOptional<T extends Record<string, unknown>> = {
    39. [K in keyof T as {} extends Pick<T, K> ? K : never]: T[K];
    40. };
    41. // type GetOptional<T> = {
    42. // [P in keyof T as T[P] extends Required<T>[P] ? never : P]: T[P]
    43. // }
    44. type I = GetOptional<{ foo: number; bar: string | undefined }>; // expected to be { bar?: string }
    45. type Test = {} extends Pick<{ foo: number; bar?: string }, "bar">
    46. ? false
    47. : true;
    48. // 题32
    49. // type RequiredKeys<T extends object, P = keyof T> =
    50. // P extends keyof T ? T[P] extends Required<T>[P] ? P : never : never;
    51. // type Result = RequiredKeys<{ foo: number; bar?: string }>;
    52. // 题33
    53. type Foo = {
    54. a: string;
    55. b: number;
    56. };
    57. type Bar = {
    58. a: string;
    59. c: boolean;
    60. };
    61. // type Diff<A, B, K = keyof A & keyof B> = {
    62. // [P in keyof A | keyof B as P extends K ? never : P ]: P extends keyof A ? A[P] : P extends keyof B ? B[P] : never;
    63. // };
    64. type Diff<T, U> = Omit<T & U, keyof T & keyof U>;
    65. type Result1 = Diff<Foo, Bar>; // { b: number, c: boolean }
    66. type Result2 = Diff<Bar, Foo>; // { b: number, c: boolean }
    67. // 题34
    68. interface Model {
    69. name: string;
    70. age: number;
    71. locations?: string[] | null;
    72. }
    73. // 这里的infer Rest是除了undefined之外的值
    74. // type ObjectEntries<T, U = keyof T> =
    75. // U extends keyof T ? [U, T[U] extends infer Rest | undefined ? Rest : T[U]] : never;
    76. // -?是必选
    77. // type ObjectEntries<T> = {
    78. // [K in keyof T]-?: [K, [Exclude<T[K], undefined>] extends [never] ? undefined : Exclude<T[K], undefined>]
    79. // }[keyof T]
    80. // type ObjectEntries<T> = {
    81. // [key in keyof T]-?: [key, T[key] extends (infer R | undefined)? R: T[key]]
    82. // }[keyof T]
    83. type ObjectEntries<
    84. T extends object,
    85. K extends keyof T = keyof T
    86. > = K extends keyof T ? [K, Required<T>[K]] : never;
    87. type modelEntries = ObjectEntries<Model>;
    88. // 题35
    89. // type Flip<T extends Record<string, any>> = {
    90. // [K in keyof T as `${T[K]}`]: K
    91. // }
    92. // type t1 = Flip<{ a: "x", b: "y", c: "z" }>; // {x: 'a', y: 'b', z: 'c'}
    93. // type t2 = Flip<{ a: 1, b: 2, c: 3 }>; // {1: 'a', 2: 'b', 3: 'c'}
    94. // type t3 = Flip<{ a: false, b: true }>; // {false: 'a', true: 'b'}
    95. // 题36
    96. // const brand = {
    97. // 全部: 'ALL',
    98. // 本品: 'SELF',
    99. // 竞品: 'COMPETITION',
    100. // } as const;
    101. // type EnumOptions<T, K = keyof T> = K extends keyof T ? {label: K; value: T[K]}[] : never;
    102. // type s1 = EnumOptions<typeof brand>;
    103. // 题37
    104. // type TupleToNestedObject<T, U> = T extends [infer J extends string, ...infer K] ? Record<J, TupleToNestedObject<K, U>> : U
    105. // type TupleToNestedObject<T extends string[], U> =
    106. // T extends [infer K, ...infer Rest] ? K extends string
    107. // ? { [Key in K]: Rest extends string[] ? TupleToNestedObject<Rest, U> : U }
    108. // : never : U;
    109. // type a = TupleToNestedObject<['a'], string> // {a: string}
    110. // type b = TupleToNestedObject<['a', 'b'], number> // {a: {b: number}}
    111. // type c = TupleToNestedObject<[], boolean> // boolean. if the tuple is empty, just return the U type
    112. // 题38
    113. const tuple = ["tesla", "model 3", "model X", "model Y"] as const;
    114. type TupleToObject<T extends readonly any[]> = {
    115. [P in T[number]]: P;
    116. };
    117. type result = TupleToObject<typeof tuple>;
    118. // expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
    119. // 题39
    120. // type DropChar<T extends string, U extends string> =
    121. // T extends string ? T extends `${infer A}${infer Rest}` ? `${U extends A ? "" : A}${DropChar<Rest, U>}` : '' : never;
    122. type DropChar<
    123. T extends string,
    124. U extends string
    125. > = T extends `${infer A}${U}${infer Rest}` ? DropChar<`${A}${Rest}`, U> : T;
    126. type Butterfly = DropChar<" b u t t e r f l y ! ", " ">; // 'butterfly!'
    127. // 题40
    128. type Union2Intersection<U> = ((x: U) => any) extends (x: infer I) => any
    129. ? I
    130. : undefined;
    131. type I1 = Union2Intersection<"foo" | 42 | true>;
    132. // 题41
    133. type Data = {
    134. foo: {
    135. bar: {
    136. value: "foobar";
    137. count: 6;
    138. };
    139. included: true;
    140. };
    141. hello: "world";
    142. };
    143. // type Get<T, K extends string> =
    144. // K extends keyof T ? T[K] : K extends `${infer S}.${infer Rest}` ? S extends keyof T
    145. // ? Get<T[S], Rest> : never : never;
    146. // K & keyof T 的结果就是 K ,这里只是为了处理T[K]的报错
    147. type Get<T, K extends string> = K extends `${infer K}.${infer R}`
    148. ? Get<T[K & keyof T], R>
    149. : T[K & keyof T];
    150. type A = Get<Data, "hello">; // 'world'
    151. type B = Get<Data, "foo.bar.value">; // 6
    152. type C = Get<Data, "foo.bar">; // { value: 'foobar', count: 6 }
    153. // 题42
    154. type StringToNumber<N> = N extends `${infer T extends number}` ? T : never;
    155. type T2 = StringToNumber<"2">;
    156. // 题43[]
    157. // type FilterOut<T extends any[], K> =
    158. // T extends [infer A, ...infer Rest] ? A extends K ? never : FilterOut<Rest, K> : never;
    159. // type FilterOut<T extends any[], F, U extends any[] = []> = T extends [infer K, ...infer R]
    160. // ? [K] extends [F]
    161. // ? FilterOut<R, F, [...U]>
    162. // : FilterOut<R, F, [...U, K]>
    163. // : U
    164. type FilterOut<T extends any[], U> = T extends [infer First, ...infer Rest]
    165. ? [First] extends [U]
    166. ? FilterOut<Rest, U>
    167. : [First, ...FilterOut<Rest, U>]
    168. : T;
    169. type Filtered = FilterOut<[1, 2, null, 3], null>; // [1, 2, 3]