Skip to content

Latest commit

 

History

History
243 lines (177 loc) · 40 KB

README.md

File metadata and controls

243 lines (177 loc) · 40 KB

Solutions to type challenges

A repository for storing all my solutions to the awesome type challenges found on https://github.com/type-challenges/type-challenges.

The title of the challenge is a hyperlink to the TS playground with the full solution and tests, and below the title is just its solution.

Easy

See challenges and solutions
type MyPick<T extends object, K extends keyof T> = {
  [Key in keyof T as Key extends K ? Key : never]: T[Key]
}
type MyReadonly<T> = {
  readonly [K in keyof T]: T[K]
}
type TupleToObject<T extends readonly (number | string | symbol)[]> = {
  [K in T[number]]: K
}
type First<T extends any[]> = T["length"] extends 0 ? never : T[0]
type Length<T extends readonly any[]> = T["length"]
type MyExclude<T, U> = T extends U ? never : T
type MyAwaited<T extends HasThen<unknown>> = 
T extends HasThen<infer R> 
? R extends HasThen<any> 
  ? MyAwaited<R> 
  : R 
: never
type If<C extends boolean, T, F> = C extends true ? T : F
type Concat<T extends any[], U extends any[]> = [...T, ...U]
type Includes<T extends readonly any[], U> = 
  T extends [infer First, ...infer Rest] 
  ? Equal<First, U> extends true 
    ? true 
    : Includes<[...Rest], U> 
  : false
type Push<T extends any[], U> = [...T, U]
type Unshift<T extends any[], U> = [U, ...T]
type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer Parameters) => any ? Parameters : never;

Medium

See challenges and solutions
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never
type MyOmit<T, K extends keyof T> = {
  [Key in keyof T as Key extends K ? never : Key]: T[Key]
}
type MyReadonly2<T, K extends keyof T = keyof T> = Omit<T, K> & {
  readonly [Key in K]: T[Key]
}
type DeepReadonly<T> = {
  readonly [K in keyof T]: 
    T[K] extends [...infer R] 
    ? readonly [...DeepReadonly<R>] 
    : T[K] extends Function 
      ? T[K] 
      : T[K] extends object 
        ? DeepReadonly<T[K]> 
        : T[K]
}
type TupleToUnion<T extends any[]> = T[number]
type Last<T extends any[], LastElement = unknown> = T extends [infer F, ...infer R] ? Last<R, F> : LastElement
type Pop<T extends any[]> = T extends [...infer AllExceptLast, infer Last] ? [...AllExceptLast] : []
declare function PromiseAll<T extends unknown[]>(values: readonly [...T]): Promise<{
  [Key in keyof T]: Awaited<T[Key]>
}>;
type LookUp<U, T> = U extends { type: infer R } ? R extends T ? U : never : never;
type LookUp<U, T> = U extends { type: infer R } ? R extends T ? U : never : never;
type ToTrim = ' ' | '\n' | '\t'
type TrimLeft<S extends string> = S extends `${ToTrim}${infer Rest}` ? TrimLeft<Rest> : S
type ToTrim = ' ' | '\n' | '\t'
type Trim<S extends string> = S extends `${ToTrim}${infer Rest}` ? Trim<Rest> : S extends `${infer Rest}${ToTrim}` ? Trim<Rest> : S
type MyCapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : Uppercase<S>
type Replace<S extends string, From extends string, To extends string> = 
From extends '' 
? S 
: S extends `${From}${infer R}` 
  ? `${To}${R}` 
  : S extends `${infer R1}${From}${infer R2}`
    ? `${R1}${To}${R2}`
    : S extends `${infer R}${From}`
      ? `${R}${To}`
      : S
type ReplaceAll<S extends string, From extends string, To extends string> =
  S extends `${infer L}${From extends '' ? never : From}${infer R}`
    ? `${L}${To}${ReplaceAll<R, From, To>}`
    : S
type AppendArgument<Fn extends Function, A> = Fn extends (...args: infer Args) => infer R ? (...args: [...Args, A]) => R : never;
type IsNever<T> = [T] extends never[] ? true : false;
type Permutation<T, I = T> = IsNever<T> extends true ? [] : I extends infer R ? [R, ...Permutation<Exclude<T, R>>] : [];