Skip to content

Instantly share code, notes, and snippets.

@ferdaber
Last active December 2, 2021 18:56
Show Gist options
  • Select an option

  • Save ferdaber/7546bb3b4c6e77a7de07edd177bc2c44 to your computer and use it in GitHub Desktop.

Select an option

Save ferdaber/7546bb3b4c6e77a7de07edd177bc2c44 to your computer and use it in GitHub Desktop.
Useful Types
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type Diff<T, U> = Omit<T, Extract<keyof U, keyof T>>
// works because {} will extend a pick of an optional property
// i.e. {} extends { foo?: string } because it's potentially undefined
// abuses the fact that the compiler treats assignability specially for object types
type OptionalKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never }[keyof T]
type RequiredKeys<T> = Exclude<keyof T, OptionalKeys<T>>
// in a weak type, the empty interface extends that type since all of its properties can be undefined
type IsWeak<T> = {} extends T ? true : false
// check by doing `true extends IsNullable<T> ? ...`
type IsNullable<T> = true extends (T extends null | undefined | void ? true : false) ? true : false
// takes advantage of conditional type short circuiting with 'any' where it unions both conditional type branches
type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false
// take advantage of how infer enumerates over keys in the implementation, and will exclude `never`s
// this no longer works as of ???
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [K in keyof T]: infer U } ? U : never;
// for ts4.1 this works
type KnownKeys<T> = {
[ P in keyof T as string extends P ? never : number extends P ? never : P ] : T[P]
}
// use to explicitly create a tuple type without widening
function tuple<T extends any[]>(...elements: T): T { return elements }
// turns a union into an intersect by switching the variance position of the assignability check
// since function parameters are checked contravariantly when checking assignability of callable types
type IntersectUnion<T> = (T extends any ? (param: T) => unknown : never) extends ((
params: infer U,
) => unknown)
? U
: never;
// infer a type without using it as a constraint, can be used to reverse contravariant type checking for function params
// P is inferred as-is and type-checked, and the full type of `func` is inferred via intersection type which is always
// compatible with its companion call signature
interface CallSignature<P, R = any> { (param: P): R }
function hof<P extends Supertype, F>(func: CallSignature<P> & F): any
// constrain a type such that all of its properties are a certain type, without making it have an index signature
type Map<T, U> = { [K in keyof T]: U }
function mapOfNumbers<E extends Map<E, U>>(map: E): void
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment