import "../_dnt.polyfills.js"; import { getOrInit } from "../util/state.js" export interface Guard { (value: T): value is Y } export function is(guard: undefined): Guard export function is(guard: null): Guard export function is(guard: typeof Number): Guard export function is(guard: typeof String): Guard export function is(guard: typeof Boolean): Guard export function is(guard: typeof BigInt): Guard export function is(guard: typeof Symbol): Guard export function is(guard: true): Guard export function is(guard: false): Guard export function is(guard: abstract new(...args: any) => T): Guard export function is< T extends string | { type: string }, U extends T extends { type: string } ? T["type"] : T, >( guard: U, ): Guard> export function is(guard: any): Guard { switch (guard) { case undefined: return isUndefined case null: return isNull case Number: return isNumber case String: return isString case Boolean: return isBoolean case BigInt: return isBigInt case Symbol: return isSymbol default: if (typeof guard === "string") { return isType(guard) } else if (typeof guard === "boolean") { return guard ? isTrue : isFalse } { return isInstance(guard) } } } function isUndefined(x: unknown): x is undefined { return typeof x === "undefined" } function isNull(x: unknown): x is null { return x === null } function isNumber(x: unknown): x is number { return typeof x === "number" } function isString(x: unknown): x is string { return typeof x === "string" } function isBoolean(x: unknown): x is boolean { return typeof x === "boolean" } function isBigInt(x: unknown): x is bigint { return typeof x === "bigint" } function isSymbol(x: unknown): x is symbol { return typeof x === "symbol" } function isTrue(x: unknown): x is true { return x === true } function isFalse(x: unknown): x is false { return x === false } function isType< T extends string | { type: string }, U extends T extends { type: string } ? T["type"] : T, >(type: U) { return (value: T): value is Extract => (value as any) === type || (value as any).type === type } const isInstanceMemo = new WeakMap any, Guard>() function isInstance(ctor: abstract new(...args: any) => T): Guard { return getOrInit( isInstanceMemo, ctor, () => (value: unknown): value is T => value instanceof ctor, ) } // Exclude === unknown // SmartExclude === {} | undefined export type SmartExclude = T2 extends null | undefined ? T1 & Exclude<{} | null | undefined, T2> : Exclude