/** Type alias for something that may or may not be wrapped in a promise. */ export type Awaitable = T | Promise /** Type alias for something that may be undefined. */ export type Maybe = T | undefined export type MaybeArr = { [Index in keyof T]: Maybe } & {length: T['length']} export type Either = Left | Right export type Left = [T, undefined] export type Right = [undefined, T] export function isLeft(what: Either): what is Left { return typeof what[1] === 'undefined' } export function isRight(what: Either): what is Right { return typeof what[0] === 'undefined' } export function left(what: T): Left { return [what, undefined] } export function right(what: T): Right { return [undefined, what] } export function unleft(what: Left): T { return what[0] } export function unright(what: Right): T { return what[1] } /** Type alias for a callback that accepts a typed argument. */ export type ParameterizedCallback = ((arg: T) => any) /** A key-value form of a given type. */ export type KeyValue = {key: string, value: T} /** Simple helper method to verify that a key is a keyof some object. */ export function isKeyof(key: unknown, obj: T): key is keyof T { if ( typeof key !== 'string' && typeof key !== 'symbol' ) { return false } return key in obj } /** A typescript-compatible version of Object.hasOwnProperty. */ export function hasOwnProperty(obj: X, prop: Y): obj is X & Record { // eslint-disable-line @typescript-eslint/ban-types return Object.hasOwnProperty.call(obj, prop) } /** * TypeScript helper for creating tagged-types. */ export interface TypeTag { readonly __typeTag: S } export type PrefixTypeArray = [T, ...TArr] export type SuffixTypeArray = [...TArr, T] export type TypeArraySignature = (...params: TArr) => TReturn export type MethodsOf any> = { [K in keyof T]: T[K] extends TMethod ? K : never }[keyof T] export type MethodType any> = { [K in keyof TClass]: TClass[K] extends TMethod ? TClass[K] : never }[TKey] export type Awaited = T extends PromiseLike ? U : T export type Integer = TypeTag<'@extollo/lib.Integer'> & number export function isInteger(num: number): num is Integer { return !isNaN(num) && parseInt(String(num), 10) === num } export type ArrayElement = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;