Last active
March 3, 2023 11:47
-
-
Save erodactyl/cb445f8e159d50883c81da57d3c6b656 to your computer and use it in GitHub Desktop.
Implementing TypeScript utility types (https://www.typescriptlang.org/docs/handbook/utility-types.html) from scratch.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* `Record<Keys, Type>` | |
* | |
* Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type | |
*/ | |
type _Record<K extends string | number | symbol, T> = { | |
[P in K]: T; | |
}; | |
/** | |
* `Awaited<Type>` | |
* | |
* This type is meant to model operations like await in async functions, or the .then() method on Promises - specifically, the way that they recursively unwrap Promises. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#awaitedtype | |
*/ | |
type _Awaited<T> = T extends { | |
then: (onfullfilled: (arg: infer R) => any) => any; | |
} | |
? _Awaited<R> | |
: T; | |
/** | |
* `Parial<Type>` | |
* | |
* Constructs a type with all properties of Type set to optional. This utility will return a type that represents all subsets of a given type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype | |
*/ | |
type _Partial<T> = T extends _Record<any, any> | |
? { | |
[K in keyof T]?: T[K]; | |
} | |
: T; | |
/** | |
* Required<Type> | |
* | |
* Constructs a type consisting of all properties of Type set to required. The opposite of Partial. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype | |
*/ | |
type _Required<T> = T extends _Record<any, any> | |
? { | |
[K in keyof T]-?: T[K]; | |
} | |
: T; | |
/** | |
* `Readonly<Type>` | |
* | |
* Constructs a type with all properties of Type set to readonly, meaning the properties of the constructed type cannot be reassigned. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype | |
*/ | |
type _Readonly<T> = T extends _Record<any, any> | |
? { | |
readonly [K in keyof T]: T[K]; | |
} | |
: T; | |
/** | |
* `Pick<Type, Keys>` | |
* | |
* Constructs a type by picking the set of properties Keys (string literal or union of string literals) from Type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys | |
*/ | |
type _Pick<T extends _Record<any, any>, K extends keyof T> = { | |
[P in K]: T[P]; | |
}; | |
/** | |
* `Omit<Type, Keys>` | |
* | |
* Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals). | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys | |
*/ | |
type _Omit<T extends _Record<any, any>, K extends string | number | symbol> = { | |
[P in keyof T as P extends K ? never : P]: T[P]; | |
}; | |
/** | |
* `Exclude<UnionType, ExcludedMembers>` | |
* | |
* Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers | |
*/ | |
type _Excluded<U, E> = U extends E ? never : U; | |
/** | |
* `Extract<Type, Union>` | |
* | |
* Constructs a type by extracting from Type all union members that are assignable to Union. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union | |
*/ | |
type _Extract<T, U> = T extends U ? T : never; | |
/** | |
* `NonNullable<Type>` | |
* | |
* Constructs a type by excluding null and undefined from Type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype | |
*/ | |
type _NonNullable<T> = T extends undefined ? never : T extends null ? never : T; | |
/** | |
* `Parameters<Type>` | |
* | |
* Constructs a tuple type from the types used in the parameters of a function type Type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype | |
*/ | |
type _Parameters<Fn extends (...args: any[]) => any> = Fn extends ( | |
...args: infer P | |
) => any | |
? P | |
: never; | |
/** | |
* `ReturnType<Type>` | |
* | |
* Constructs a type consisting of the return type of function Type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype | |
*/ | |
type _ReturnType<Fn extends (...args: any[]) => any> = Fn extends ( | |
...args: any[] | |
) => infer R | |
? R | |
: never; | |
/** | |
* `ConstructorParameters<Type>` | |
* | |
* Constructs a tuple or array type from the types of a constructor function type. It produces a tuple type with all the parameter types (or the type never if Type is not a function). | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#constructorparameterstype | |
*/ | |
type _ConstructorParameters<T extends abstract new (...args: any[]) => any> = | |
T extends abstract new (...args: infer P) => any ? P : never; | |
/** | |
* `ThisParameterType<Type>` | |
* | |
* Extracts the type of the this parameter for a function type, or unknown if the function type has no this parameter. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#thisparametertypetype | |
*/ | |
type _ThisParameterType<T> = T extends (this: infer This, ...args: any[]) => any | |
? This | |
: unknown; | |
/** | |
* `InstanceType<Type>` | |
* | |
* Constructs a type consisting of the instance type of a constructor function in Type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype | |
*/ | |
type _InstanceType<T extends abstract new (...args: any[]) => any> = | |
T extends abstract new (...args: any[]) => infer R ? R : never; | |
/** | |
* `OmitThisParameter<Type>` | |
* | |
* Removes the this parameter from Type. If Type has no explicitly declared this parameter, the result is simply Type. Otherwise, a new function type with no this parameter is created from Type. Generics are erased and only the last overload signature is propagated into the new function type. | |
* | |
* https://www.typescriptlang.org/docs/handbook/utility-types.html#omitthisparametertype | |
*/ | |
type _OmitThisParameter<T> = T extends ( | |
this: any, | |
...args: infer Args | |
) => infer Res | |
? (...args: Args) => Res | |
: T; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment