const secret = Symbol('secret') type Secret = typeof secret type IsNever = [T] extends [never] ? 1 : 0 type Not = T extends 1 ? 0 : 1 type IsAny = [T] extends [Secret] ? Not> : 0 type OneOf = T extends 1 ? 1 : U export type IsNeverOrAny = OneOf, IsAny> export class RichError extends Error { private constructor(public details: unknown) { super(JSON.stringify(details, null, 2)) } public static thrower(context: string) { return (info?: T): never => RichError.throw({context, details: info}) } public static throw(details?: T): never { const resolvedDetails = details || {details: 'none!'} throw Object.assign(new RichError(resolvedDetails), {details: resolvedDetails}) } } export const funcLabel = (func: Function) => func.name || func .toString() .split('\n') .filter((_, i, arr) => i === 0 || i === arr.length - 1) .map(line => line.trim()) .join(' ... ')