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.
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;
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>>] : [];