TypeScript | Type Challenges
Implement the built-in Pick<T, K>
generic without using it.
// type MyPick<T, K> = K extends keyof T ? { [P in K]: T[P] } : {}
type MyPick<T, K extends keyof T> = { [P in K]: T[P] }
Implement the built-in Readonly<T>
generic without using it.
type MyReadonly<T> = {
readonly [P in keyof T]: T[P]
}
Given an array, transform to a object type and the key/value must in the given array.
type TupleToObject<T extends readonly any[]> = {
[K in T[number]]: K
}
Implement a generic First that takes an Array T and returns it's first element's type.
type First<T extends any[]> = T extends [infer A, ...any] ?
A : never
For given a tuple, you need create a generic Length, pick the length of the tuple.
type Length<T extends readonly any[]> = T["length"]
Implement the built-in Exclude<T, U>
.
type MyExclude<T, U> = T extends U ? never : T
If we have a type which is wrapped type like Promise. How we can get a type which is inside the wrapped type? For example if we have Promise<ExampleType>
how to get ExampleType
?
type Awaited<T> = T extends Promise<infer R> ? R : never
Implement a utils If which accepts condition C
, a truthy return type T
, and a falsy return type F
. C
is expected to be either true
or false
while T
and F
can be any type.
type If<C extends true | false, T, F> = C extends true ? T : F
Implement the JavaScript Array.concat
function in the type system. A type takes the two arguments. The output should be a new array that includes inputs in ltr order
type Concat<T extends any[], U extends any[]> = [...T, ...U]
Implement the JavaScript Array.includes
function in the type system. A type takes the two arguments. The output should be a boolean true
or false
.
type Includes<T extends readonly any[], U> = U extends T[number] ? true : false
Implement the built-in ReturnType<T>
generic without using it.
type MyReturnType<T> = T extends (..._: any[]) => infer R ? R : never
Implement the built-in Omit<T, K>
generic without using it.
type MyOmit<T, K> = Pick<T, Exclude<keyof T, K>>
Implement a generic MyReadonly2<T, K>
which takes two type argument T
and K
.
K
specify the set of properties of T
that should set to Readonly. When K
is not provided, it should make all properties readonly just like the normal Readonly<T>
.
type Flatten<T extends { [key: string]: any }> = { [key in keyof T]: T[key] }
type MyReadonly2<T, K extends keyof T = keyof T> = Flatten<T & { readonly [S in K]: T[S] }>
Implement a generic DeepReadonly<T>
which make every parameter of an object - and its sub-objects recursively - readonly.
type DeepReadonly<T> = keyof T extends never ? T : { readonly [P in keyof T]: DeepReadonly<T[P]> }
Implement a generic TupleToUnion<T>
which covers the values of a tuple to its values union.
type TupleToUnion<T extends any[]> = T extends [_: infer H, ..._: infer Rest] ? (H | TupleToUnion<Rest>) : never
Implement an object to provide two function option(key, value)
and get()
- In
option
, you can extend the current config type by the given key and value. - We should about to access the final config type via
get
.
type Flatten<T extends Record<string, any>> = { [key in keyof T]: T[key] }
type Extend<O extends Record<string, any>, K extends string, T> = Flatten<O & { [S in K]: T }>
type Chainable<Options = {}> = {
option<K extends string, T>(key: K, value: T): Chainable<Extend<Options, K, T>>
get(): Options
}
Implement a generic Last<T>
that takes an Array T
and returns it's last element's type.
type Last<T extends any[]> = T extends [...any, infer A] ? A : never
Implement a generic Pop<T>
that takes an Array T
and returns an Array without it's last element.
type Pop<T extends any[]> = T extends [...infer A, any] ? A : never
Type the function PromiseAll
that accepts an array of PromiseLike objects, the returning value should be Promise<T>
where T
is the resolved result array.
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
[P in keyof T]: Awaited<T[P]>
}>