The answers of type challenge
Warm-up
Hello World
type HelloWorld = string;
Easy
Pick
type MyPick<T, K extends keyof T> = { [Key in K]: T[Key] };
Readonly
type MyReadonly<T> = { readonly [P in keyof T]: T[P] };
TupleToObject
type TupleToObject<T extends ReadonlyArray<any>> = {
[P in T[number]]: P;
};
First Of Array
type First<T extends any[]> = T["length"] extends 0 ? never : T[0];
type First<T extends any[]> = T extends [infer F, ...infer Rest] ? F : never;
Length Of Tuple
type Length<T extends ReadonlyArray<any>> = T["length"];
Exclude
type MyExclude<T, U> = T extends U ? never : T;
Awaited
type MyAwaited<T> = T extends Promise<infer U> ? MyAwaited<U> : T;
If
type If<C extends boolean, T, F> = C extends true ? T : F;
Concat
type Concat<T extends ReadonlyArray<any>, U extends ReadonlyArray<any>> = [
...T,
...U
];
Includes
type isEqual<X, Y> = (<F>() => F extends X ? 1 : 2) extends <S>() => S extends Y
? 1
: 2
? true
: false;
type Includes<T extends readonly any[], U> = T extends [infer F, ...infer Rest]
? isEqual<F, U> extends true
? true
: Includes<Rest, U>
: false;
Push
type Push<T extends any[], U> = [...T, U];
Unshift
type Unshift<T extends unknown[], U> = [U, ...T];
Parameters
type MyParameters<T extends (...args: any[]) => any> = T extends (
...args: infer A
) => any
? A
: never;
Medium
Get Return Type
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
Omit
type MyOmit<T, K> = Pick<T, Exclude<keyof T, K>>;
Readonly 2
type MyReadonly2<T, K = keyof T> = {
readonly [Key in keyof T as Key extends K ? Key : never]: T[Key];
} & { [Key in keyof T as Key extends K ? never : Key]: T[Key] };
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P];
} & Omit<T, K>;
Deep Readonly
type DeepReadonly<T> = T extends Function
? T
: T extends object
? { readonly [P in keyof T]: DeepReadonly<T[P]> }
: T;
type PrimitiveType = number | string | boolean;
type AtomicObject = Function | Promise<any> | Date | RegExp;
type WeakReferences = WeakMap<any, any> | WeakSet<any>;
type Immutable<T> = T extends PrimitiveType
? T
: T extends AtomicObject
? T
: T extends ReadonlyMap<infer K, infer V>
? ReadonlyMap<Immutable<K>, Immutable<V>>
: T extends ReadonlySet<infer V>
? ReadonlySet<Immutable<V>>
: T extends WeakReferences
? T
: T extends object
? { readonly [K in keyof T]: Immutable<T[K]> }
: T;
TupleToUnion
type TupleToUnion<T extends any[]> = T extends [infer F, ...infer Rest]
? F | TupleToUnion<Rest>
: never;
type TupleToUnion<T extends any[]> = T[number];
Chainable Options
type Chainable<Pre = {}> = {
option<K extends string, V>(
key: K extends keyof Pre ? never : K,
value: V
): Chainable<Pre & { [key in K]: V }>;
get(): Pre;
};
Last Of Array
type Last<T extends any[]> = T extends [...infer Rest, infer L] ? L : never;
type Last<T extends any[]> = T extends [infer F, ...infer Rest]
? T["length"] extends 1
? F
: Last<Rest>
: never;
Pop
type Pop<T extends any[]> = T extends [...infer Rest, infer L] ? Rest : [];
Promise.All
type MyAwaited<T> = T extends Promise<infer U> ? MyAwaited<U> : T;
declare function PromiseAll<T extends readonly unknown[] | []>(
values: T
): Promise<{ -readonly [P in keyof T]: MyAwaited<T[P]> }>;
LookUp
type LookUp<U, T> = U extends { type: T } ? U : never;
TrimLeft
type TrimLeft<S extends string> = S extends `${WhiteSpace}${infer Rest}`
? TrimLeft<Rest>
: S;
Trim
type WhiteSpace = " " | "\t" | "\n";
type TrimLeft<S extends string> = S extends `${WhiteSpace}${infer Rest}`
? TrimLeft<Rest>
: S;
type TrimRight<S extends string> = S extends `${infer Rest}${WhiteSpace}`
? TrimRight<Rest>
: S;
type Trim<S extends string> = TrimLeft<TrimRight<S>>;
Capitalize
type MyCapitalize<S extends string> = S extends `${infer F}${infer Rest}`
? `${Uppercase<F>}${Rest}`
: S;
Replace
type Replace<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer F}${From}${infer L}`
? `${F}${To}${L}`
: S;
Replace All
type ReplaceAll<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer F}${From}${infer L}`
? `${F}${To}${ReplaceAll<L, From, To>}`
: S;
AppendArgument
type AppendArgument<Fn extends (...args: any[]) => any, I> = Fn extends (
...args: infer A
) => infer R
? (...args: [...A, I]) => R
: never;
type AppendArgument<Fn extends (...args: any[]) => any, I> = (
...args: [...Parameters<Fn>, I]
) => ReturnType<Fn>;
Permutation
type Permutation<T extends keyof any> = [T] extends [never]
? []
: { [P in T]: [P, ...Permutation<Exclude<T, P>>] }[T];
LengthOfString
type LengthOfString<
S extends string,
A extends any[] = []
> = S extends `${infer L}${infer R}`
? LengthOfString<R, [...A, L]>
: A["length"];
Flatten
type Flatten<Els extends unknown[]> = Els extends [infer F, ...infer R]
? F extends unknown[]
? [...Flatten<F>, ...Flatten<R>]
: [F, ...Flatten<R>]
: [];
AppendToObject
type AppendToObject<T extends object, U extends string, V> = {
[K in keyof T | U]: K extends keyof T ? T[K] : V;
};
Absolute
type Absolute<T extends number | string | bigint> = `${T}` extends `-${infer R}`
? R
: `${T}`;
StringToUnion
type StringToUnion<T extends string> = T extends `${infer F}${infer R}`
? F | StringToUnion<R>
: never;
Merge
type Merge<F extends object, S extends object> = {
[K in keyof F | keyof S]: K extends keyof S
? S[K]
: K extends keyof F
? F[K]
: never;
};
ConverToKebCase
type converToKebCase<S extends string> = S extends `${infer H}${infer Rest}`
? H extends Uncapitalize<H>
? `${H}${converToKebCase<Rest>}`
: `-${Uncapitalize<H>}${converToKebCase<Rest>}`
: "";
type KebabCase<S extends string> = converToKebCase<Uncapitalize<S>>;
Diff
type Diff<F, S> = {
[K in keyof F | keyof S as K extends keyof F
? K extends keyof S
? never
: K
: K extends keyof S
? K
: never]: K extends keyof F
? K extends keyof S
? never
: F[K]
: K extends keyof S
? S[K]
: never;
};
AnyOf
type Empty = 0 | "" | false | [];
type isEmpty<T> = T extends Empty
? false
: T extends {}
? keyof T extends never
? false
: true
: false;
type AnyOf<T extends readonly any[]> = T extends [infer F, ...infer Rest]
? isEmpty<F> extends true
? true
: AnyOf<Rest>
: false;
IsNever
type IsNever<T> = [T] extends [never] ? true : false;