import { Get } from './Get'; import { isFunc } from './Func'; import { isDefined, isFunction } from './Is'; import { isPrimitive } from './Primitive'; import { Optional } from './Types'; export type Constructor = { new (...args: any[]): T }; export type Construct = Get | Constructor; export const isConstructor = (c?: unknown): c is Constructor => (isDefined(c) && isFunc(c) && c.prototype && c.prototype.constructor) === c; export const isInstance = (ctor: Constructor, o?: unknown): o is T => isFunction(ctor) && o instanceof ctor; export const ofConstruct = (c: Construct, ...args: unknown[]): T => (isConstructor(c) ? new c(...args) : isFunc(c) ? c(...args) : c); export const toName = (subject?: unknown, postfix = ''): string => (subject as any)?.constructor?.name?.replace(postfix, '').toLowerCase() ?? ''; const isPromise = (value: unknown): value is Promise => { return value instanceof Promise; }; export const on = (t: T, f: (t: T) => R): R extends Promise ? Promise : T => { const result = f(t); return (isPromise(result) ? result.then(() => t) : t) as R extends Promise ? Promise : T; }; export const use = (t: T, f: (t: T) => Out): Out => f(t); export const ifA = (c: Constructor, t?: unknown, alt?: unknown): Optional => (!isPrimitive(t) && t instanceof c ? t : alt ? ifA(c, alt) : undefined); export type RequireAtLeastOne = Pick> & { [K in Keys]-?: Required> & Partial>>; }[Keys];