Skip to content
forked from joonhocho/tsdef

TypeScript common pattern shortcut definitions / utility gist library

License

Notifications You must be signed in to change notification settings

leandrit1/tsdef

 
 

Repository files navigation

tsdef

TypeScript common patterns shortcuts definitions snippets utility gist library

export type nil = null | undefined;

export type Nilable<T> = T | nil;
export type Nullable<T> = T | null;
export type Undefinable<T> = T | undefined;

export type MaybeNil<T> = T | nil;
export type MaybeNull<T> = T | null;
export type MaybeUndefined<T> = T | undefined;
export type MaybePromise<T> = T | Promise<T>;
export type MaybeArray<T> = T | T[];
export type MaybeAsReturnType<T> = T | ((...args: any) => T);

// removes both null or undefined from T
export type NonNil<T> = T extends nil ? never : T;

// removes null from T
export type NonNull<T> = T extends null ? never : T;

// removes undefined from T
export type NonUndefined<T> = T extends undefined ? never : T;

// make all properties nilable
export type NilableProps<T> = { [P in keyof T]?: T[P] | nil };

// make all properties nullable
export type NullableProps<T> = { [P in keyof T]: T[P] | null };

// make all properties undefinable
export type UndefinableProps<T> = { [P in keyof T]?: T[P] | undefined };

// make all properties non nilable
export type NonNilProps<T> = { [P in keyof T]-?: NonNil<T[P]> };

// make all properties non null
export type NonNullProps<T> = { [P in keyof T]: NonNull<T[P]> };

// make all properties non undefined
export type NonUndefinedProps<T> = { [P in keyof T]-?: NonUndefined<T[P]> };

export type RequiredProps<T> = { [P in keyof T]-?: T[P] };

// string | number | symbol
export type AnyKey = keyof any;

// matches any functions
export type AnyFunction = (...args: any) => any;

// matches any constructors
export type AnyConstructor = new (...args: any) => any;

// matches classes
export interface AnyClass {
  prototype: any;
  new (...args: any): any;
}

// matches prototypes
export interface AnyPrototype {
  constructor: any;
}

// matches any objects
export interface AnyObject {
  [key: string]: any;
  [key: number]: any;
}

// matches objects with string keys
export interface AnyObjectWithStringKeys {
  [key: string]: any;
}

// matches objects with number keys
export interface AnyObjectWithNumberKeys {
  [key: number]: any;
}

// without some keys
export type ExcludeKeys<T, K extends AnyKey> = Omit<T, K>;

// values of object
export type ValueOf<T> = T[keyof T];

// get a property
export type Property<T, K> = K extends keyof T ? T[K] : never;

// get keys with values of given type
export type KeyOfType<T, U> = {
  [P in keyof T]-?: T[P] extends U ? P : never
}[keyof T];

// get keys with values of given sub type
// For some reason, this works and KeyOfType doesn't when U = undefined
export type KeyOfSubType<T, U> = {
  [P in keyof T]-?: U extends T[P] ? P : never
}[keyof T];

// make some keys optional
export type WithOptionalKeys<T, K extends keyof T> = Omit<T, K> &
  Partial<Pick<T, K>>;

// make some keys nilable
export type WithNilableKeys<T, K extends keyof T> = Omit<T, K> &
  NilableProps<Pick<T, K>>;

// make some keys nullable
export type WithNullableKeys<T, K extends keyof T> = Omit<T, K> &
  NullableProps<Pick<T, K>>;

// make some keys undefinable
export type WithUndefinableKeys<T, K extends keyof T> = Omit<T, K> &
  UndefinableProps<Pick<T, K>>;

// make some keys non nil
export type WithNonNilKeys<T, K extends keyof T> = Omit<T, K> &
  NonNilProps<Pick<T, K>>;

// make some keys non null
export type WithNonNullKeys<T, K extends keyof T> = Omit<T, K> &
  NonNullProps<Pick<T, K>>;

// make some keys non undefined
export type WithNonUndefinedKeys<T, K extends keyof T> = Omit<T, K> &
  NonUndefinedProps<Pick<T, K>>;

// first object properties excluding common keys with second object
export type DiffObjects<T, U> = Omit<T, keyof U>;

// union of two objects
export type UnionObjects<
  T extends AnyObject,
  U extends AnyObject
> = DiffObjects<T, U> &
  { [P in keyof T & keyof U]: T[P] | U[P] } &
  DiffObjects<U, T>;

// similar to Object.assign
export type OverwriteProps<T, U> = U & DiffObjects<T, U>;

// get arguments type
export type Arguments<T extends AnyFunction> = Parameters<T>;

// get arguments type
export type FirstArgument<T extends AnyFunction> = T extends (
  arg: infer A,
  ...args: any
) => any
  ? A
  : never;

// get return value type
export type Return<T extends AnyFunction> = ReturnType<T>;

// get return type if a function, otherwise return itself
export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;

// get instance type of class
export type InstanceOf<T extends AnyConstructor> = InstanceType<T>;

// get promise return type
// PromisedType<Promise<T>> = T
export type PromisedType<T extends Promise<any>> = T extends Promise<infer R>
  ? R
  : never;

// get promise return type if promise, otherwise return itself
// MaybePromisedType<T | Promise<T>> = T
export type MaybePromisedType<T> = T extends Promise<infer R> ? R : T;

// get promise return type
export type MaybeAsyncReturnType<T extends AnyFunction> = MaybePromisedType<
  ReturnType<T>
>;

// get array item type
export type ItemType<T extends any[]> = T extends Array<infer I> ? I : never;

// get thunk for type
export type Thunk<T> = () => T;

// get thunk or self
export type MaybeThunk<T> = T | Thunk<T>;

// get return type of thunk
export type Unthunk<T extends Thunk<any>> = T extends Thunk<infer R>
  ? R
  : never;

// get return type if thunk, otherwise get self
export type MaybeUnthunk<T> = T extends Thunk<infer R> ? R : T;

// get inferred type of array item or return value or promised value
export type Unpack<T> = T extends Array<infer I>
  ? I
  : T extends (...args: any) => infer R
  ? R
  : T extends Promise<infer P>
  ? P
  : T;

// InheritClass<C1, C2>: class C1 extends C2 {}
export type InheritClass<C1 extends AnyClass, C2 extends AnyClass> = {
  prototype: OverwriteProps<C2['prototype'], C1['prototype']>;
  new (...args: ConstructorParameters<AnyClass>): OverwriteProps<
    C2['prototype'],
    C1['prototype']
  >;
} & OverwriteProps<C2, C1>;

// return Then if T is not null nor undefined, otherwise return False
// test null and undefined separately to prevent side effect from args distribution
export type IsNonNil<T, True, False = never> = null extends T
  ? False
  : undefined extends T
  ? False
  : True;

// return True if T is not null, otherwise return False
export type IsNonNull<T, True, False = never> = null extends T ? False : True;

// return True if T is not undefined, otherwise return False
export type IsNonUndefined<T, True, False = never> = undefined extends T
  ? False
  : True;

// return True if T is `never`, otherwise return False
// wrap with array to prevent args distributing
export type IsNever<T, True, False = never> = [T] extends [never]
  ? True
  : False;

// return True if T is `any`, otherwise return False
export type IsAny<T, True, False = never> = (
  | True
  | False) extends (T extends never ? True : False)
  ? True
  : False;

// return True if T is `unknown`, otherwise return False
export type IsUnknown<T, True, False = never> = unknown extends T
  ? IsAny<T, False, True>
  : False;

// return True if T strictly includes U, otherwise return False
export type StrictlyIncludes<T, U, True, False = never> = Exclude<
  U,
  T
> extends never
  ? (IsAny<T, 1, 0> extends 1
      ? True
      : (IsAny<U, 1, 0> extends 1
          ? False
          : (IsUnknown<T, 1, 0> extends 1 ? IsUnknown<U, True, False> : True)))
  : False;

// tests and returns True if they are equal, False otherwise.
// wrap with array and do both ways to prevent args distrubition
export type AreStrictlyEqual<T, U, True, False = never> = StrictlyIncludes<
  T,
  U,
  1,
  0
> extends 1
  ? StrictlyIncludes<U, T, True, False>
  : False;

// tests and returns True if both objects have same keys, False otherwise.
export type HaveSameKeys<T, U, True, False = never> = (
  | Exclude<keyof T, keyof U>
  | Exclude<keyof U, keyof T>) extends never
  ? True
  : False;

// https://github.com/Microsoft/TypeScript/issues/26051
export type Exact<T, X extends T> = T &
  { [K in keyof X]: K extends keyof T ? X[K] : never };
// U extends Exact<{ [K in keyof T]-?: (v: T[K]) => any }, U>

About

TypeScript common pattern shortcut definitions / utility gist library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 93.4%
  • JavaScript 6.6%