UNPKG

base-up

Version:

A modern TypeScript utility library.

970 lines (957 loc) 95.5 kB
/** * Determines whether the types are strictly the same or not. * This was implemented with reference to: {@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650} * @example * Equals<123, 123> equals true * Equals<123, 456> equals false * Equals<123, number> equals false * Equals<void, undefined> equals false * Equals<any, unknown> equals false * Equals<never, any> equals false * @example * Equals<'a' | 'b', 'b' | 'a'> equals true * Equals<1, 1 | never> equals true * Equals<boolean, true | false> equals true * @example * Equals<string & {}, string> equals false * Equals<string & {}, {}> equals false * @example * Equals<[a: string], [b: string]> equals true * Equals<[string?], [] | [string]> equals false */ type Equals<T, U, Then = true, Else = false> = (<R>() => R extends T ? 1 : 2) extends <R>() => R extends U ? 1 : 2 ? Then : Else; /** * A function of the === operator with improved types. * Narrowing is possible on both the left-hand and right-hand sides. * @example * let value = Date.now() % 2 * if (equals(value, 0)) { * // Here, the value is of type 0. * } */ declare function equals<const T, const U extends T>(self: T, other: U): self is U; declare function equals<const T extends U, const U>(self: T, other: U): other is T; declare function equals<const T, const U>(self: T, other: U): false; /** * Determines whether the given type is one of the types in the tuple. * @example * IsOneOf<string, [string, number, bigint]> equals true * IsOneOf<string, [number, bigint]> equals false * IsOneOf<string, [any, unknown, never]> equals false * IsOneOf<string, [string | number]> equals false * IsOneOf<1 | 2, [1, 2]> equals false * IsOneOf<'text', [string]> equals false * IsOneOf<any, []> equals false */ type IsOneOf<T, U extends readonly unknown[], Then = true, Else = false> = U extends readonly [ infer H, ...infer L ] ? Equals<T, H> extends true ? Then : IsOneOf<T, L, Then, Else> : Else; /** * Determines whether the given value is one of the value in the tuple. * @example * isOneOf(2, 1, 2, 3) returns true * isOneOf(4, 1, 2, 3) returns false * isOneOf(1) returns false * @example Narrowing * let value = Date.now() % 5 * if (isOneOf(value, 0, 1)) { * // Here, the value is of type 0 | 1. * } */ declare function isOneOf<const T extends readonly unknown[]>(self: unknown, ...values: T): self is T[number]; declare function isNotOneOf(self: unknown, ...values: readonly unknown[]): boolean; declare const isNull: (value: unknown) => value is null; declare const isUndefined: (value: unknown) => value is undefined; declare const isNullish: (value: unknown) => value is nullish; declare const isBoolean: (value: unknown) => value is boolean; declare const isNumber: (value: unknown) => value is number; declare const isBigint: (value: unknown) => value is bigint; declare const isString: (value: unknown) => value is string; declare const isSymbol: (value: unknown) => value is symbol; declare const isFunction: (value: unknown) => value is Function; declare const isObject: (value: unknown) => value is object; declare const isNotNull: <T>(value: T | null) => value is T; declare const isNotUndefined: <T>(value: T | undefined) => value is T; declare const isNotNullish: <T>(value: T | nullish) => value is T; declare const isNotBoolean: <T>(value: T | boolean) => value is T; declare const isNotNumber: <T>(value: T | number) => value is T; declare const isNotBigint: <T>(value: T | bigint) => value is T; declare const isNotString: <T>(value: T | string) => value is T; declare const isNotSymbol: <T>(value: T | symbol) => value is T; declare const isNotFunction: <T>(value: T | Function) => value is T; declare const isNotObject: <T>(value: T | symbol) => value is T; /** * @example * isTruthy(false) returns false * isTruthy(undefined) returns false * isTruthy(null) returns false * isTruthy(0) returns false * isTruthy(0n) returns false * isTruthy('') returns false * isTruthy(NaN) returns false * @example * isTruthy(true) returns true * isTruthy(1) returns true * isTruthy(1n) returns true * isTruthy('a') returns true * isTruthy({}) returns true * isTruthy([]) returns true * isTruthy(() => {}) returns true */ declare function isTruthy(value: false | null | undefined | 0 | 0n | ''): false; declare function isTruthy<T>(value: T | false | null | undefined | 0 | 0n | ''): value is T; /** * @example * isFalsy(false) returns true * isFalsy(undefined) returns true * isFalsy(null) returns true * isFalsy(0) returns true * isFalsy(0n) returns true * isFalsy('') returns true * isFalsy(NaN) returns true * @example * isFalsy(true) returns false * isFalsy(1) returns false * isFalsy(1n) returns false * isFalsy('a') returns false * isFalsy({}) returns false * isFalsy([]) returns false * isFalsy(() => {}) returns false */ declare function isFalsy(value: false | null | undefined | 0 | 0n | ''): true; declare function isFalsy(value: unknown): value is false | null | undefined | number | 0n | ''; declare function isInstanceOf<T extends abstract new (..._: any) => any>(value: unknown, ctor: T): value is InstanceType<T>; declare function isNotInstanceOf<T extends abstract new (..._: any) => any, U>(value: U, ctor: T): value is Exclude<U, InstanceType<T>>; /** * @example * assertTypeEquality<string, any>() results in a type error * assertTypeEquality<123, 123>() does not result in a type error */ declare function assertTypeEquality<T, U>(..._: Equals<T, U> extends true ? [] : [error: [T, 'is not equal to', U]]): void; declare function assert<T, U extends T>(value: T, predicate: (value: T) => value is U): asserts value is U; declare function assert<T>(value: T, predicate: (value: T) => boolean): void; declare function assertEqual<T, U extends T>(lhs: T, rhs: U): asserts lhs is U; declare function assertEqual<T extends U, U>(lhs: T, rhs: U): asserts rhs is T; declare function assertEqual<T, U>(lhs: T, rhs: U): never; declare function assertInstanceOf<T extends abstract new (..._: any) => any>(value: unknown, ctor: T): asserts value is InstanceType<T>; /** * @example * let status: 'on' | 'off' = 'on' * switch (status) { * case 'on': * break * case 'off': * break * default: * assertNeverType(status) * } */ declare function assertNeverType(mustBeNever: never): never; /** Alias for null | undefined type */ type nullish = null | undefined; /** * Removes readonly modifier. * @example * Writable<{ readonly a: number }> equals { a: number } * Writable<readonly string[]> equals string[] * @example It does not apply to nested types. * Writable<{ nested: { readonly a: number } }> equals { nested: { readonly a: number } } * Writable<[readonly boolean[]]> equals [readonly boolean[]] */ type Writable<T> = { -readonly [K in keyof T]: T[K]; }; declare const DEFAULT_BRAND: unique symbol; type Branded<T, Brand extends keyof any = typeof DEFAULT_BRAND> = T & Record<Brand, never>; /** * Convert a literal type to its corresponding primitive type. * @example * ToBasePrimitiveType<'a'> equals string * ToBasePrimitiveType<1> equals number * ToBasePrimitiveType<true> equals boolean * ToBasePrimitiveType<undefined> equals undefined * ToBasePrimitiveType<null> equals null * @example * ToBasePrimitiveType<1 | 'a'> equals number | string */ type ToBasePrimitiveType<T> = T extends T ? IsOneOf<T, [any, never, boolean]> extends true ? T : T extends string ? string : T extends number ? number : T extends bigint ? bigint : T extends boolean ? boolean : T extends symbol ? symbol : T : never; declare const lazyKey: unique symbol; /** One of the utilities to avoid the recursion limit */ interface Lazy<T> { [lazyKey]: T; } /** One of the utilities to avoid the recursion limit */ type Unlazy<T> = T extends { [lazyKey]: unknown; } ? Unlazy<ReduceLazy<T>> : T; type ReduceLazy<T> = T extends { [lazyKey]: never; } ? never : T extends { [lazyKey]: { [lazyKey]: { [lazyKey]: { [lazyKey]: infer U; }; }; }; } ? { [lazyKey]: ReduceLazy<U>; } : T extends { [lazyKey]: { [lazyKey]: { [lazyKey]: infer U; }; }; } ? U : T extends { [lazyKey]: { [lazyKey]: infer U; }; } ? U : T extends { [lazyKey]: infer U; } ? U : T; /** A type that is neither a class nor an object or array containing a class. */ type NeitherClassNorContainsClass = null | undefined | boolean | number | bigint | string | symbol | ((..._: readonly unknown[]) => unknown) | readonly NeitherClassNorContainsClass[] | { readonly [key: keyof any]: NeitherClassNorContainsClass; }; declare const OMITTED: unique symbol; /** The default type of the type parameters */ type OMITTED = typeof OMITTED; /** * @example * MaxLengthArray<2> equals [] | [unknown] | [unknown, unknown] * MaxLengthArray<3, Date> equals [] | [Date] | [Date, Date] | [Date, Date, Date] * MaxLengthArray<0, string> equals [] * @example * MaxLengthArray<number, string> equals string[] */ type MaxLengthArray<N extends number, T = unknown> = FixedLengthArray<IntegerRangeThrough<N>, T>; type ReadonlyMaxLengthArray<N extends number, T = unknown> = Readonly<MaxLengthArray<N, T>>; declare function isMaxLengthArray<T, N extends number>(self: T[], length: N): self is MaxLengthArray<N, T>; declare function isMaxLengthArray<T, N extends number>(self: readonly T[], length: N): self is ReadonlyMaxLengthArray<N, T>; declare function isMaxLengthArray<N extends number>(self: unknown, length: N): self is MaxLengthArray<N>; declare function shuffle<const T extends readonly unknown[]>(self: T): FixedLengthArray<T['length'], T[number]>; /** * @example * IsTuple<[]> equals true * IsTuple<[1, 2, 3]> equals true * IsTuple<[1, ...0[]]> equals true * IsTuple<[1, 2?, 3?]> equals true * IsTuple<number[]> equals false * IsTuple<readonly any[]> equals false */ type IsTuple<T extends readonly unknown[]> = T extends T ? IsOneOf<T, [any, T[number][], readonly T[number][]], false, true> : never; /** * @example * DestructTuple<[1, 2, ...3[], 4, 5]> equals { leading: [1, 2]; optional: []; rest: 3[]; trailing: [4, 5] } * DestructTuple<[1, 2?, ...3[]]> equals { leading: [1]; optional: [2]; rest: 3[]; trailing: [] } * DestructTuple<Date[]> equals { leading: []; optional: []; rest: Date[]; trailing: [] } * DestructTuple<[]> equals { leading: []; optional: []; rest: []; trailing: [] } */ type DestructTuple<T extends readonly unknown[], Leading extends readonly unknown[] = [], Optional extends readonly unknown[] = [], Trailing extends readonly unknown[] = []> = Equals<T, any> extends true ? { leading: []; optional: []; rest: any[]; trailing: []; } : T extends readonly [infer H, ...infer L] ? DestructTuple<L, [...Leading, H], Optional, Trailing> : T extends readonly [...infer L, infer H] ? DestructTuple<L, Leading, Optional, [H, ...Trailing]> : IsTuple<T> extends false ? { leading: Leading; optional: Optional; rest: T; trailing: Trailing; } : T extends readonly [] ? { leading: Leading; optional: Optional; rest: T; trailing: Trailing; } : T extends readonly [(infer H)?, ...infer L] ? DestructTuple<L, Leading, [...Optional, H], Trailing> : never; declare function cartesianProductOf<const T extends readonly unknown[], const U extends readonly unknown[]>(lhs: T, rhs: U): [T[number], U[number]][]; declare function permutationOf<T>(self: readonly T[], n?: number): (readonly T[])[]; /** * @example * createNGrams([1, 2, 3], 2) returns [[1, 2], [2, 3]] * createNGrams([1, 2, 3], 3) returns [[1, 2, 3]] * createNGrams([1, 2, 3], 1) returns [[1], [2], [3]] */ declare function createNGrams<const T extends readonly unknown[], N extends number>(self: T, n: N): T[number][][]; /** * @example * PrefixesOf<[1, 2, 3]> returns [[], [1], [1, 2], [1, 2, 3]] */ type PrefixesOf<T extends readonly unknown[]> = IsTuple<T> extends false ? T[] : PrefixesOfForTuple<T>; type PrefixesOfForTuple<T extends readonly unknown[], R extends readonly unknown[] = []> = T extends readonly [ infer H, ...infer L ] ? [R, ...PrefixesOfForTuple<L, [...R, H]>] : IsTuple<T> extends false ? [R, [...R, ...T]] : [R]; /** * @example * prefixesOf([1, 2, 3]) returns [[], [1], [1, 2], [1, 2, 3]] * prefixesOf([]) returns [[]] */ declare function prefixesOf<T>(self: readonly T[]): NonEmptyArray<readonly T[]>; declare function filter<T = never>(self: readonly [], f: (_: T) => boolean): []; declare function filter<T, U extends T>(self: readonly T[], f: (_: T) => _ is U): U[]; declare function filter<T>(self: readonly T[], f: (_: T) => boolean): T[]; declare function partition<T>(self: readonly [], f: (_: T) => boolean): [[], []]; declare function partition<T, U extends T>(self: readonly T[], f: (_: T) => _ is U): [U[], Exclude<T, U>[]]; declare function partition<T>(self: readonly T[], f: (_: T) => boolean): [T[], T[]]; /** * @example * Take<[0, 1, 2], 0> equals [] * Take<[0, 1, 2], 1> equals [0] * Take<[0, 1, 2], 2> equals [0, 1] * Take<[0, 1, 2], 3> equals [0, 1, 2] * Take<[0, 1, 2], 4> equals [0, 1, 2] * @example * Take<Date[], 2> equals [Date, Date] | [Date] | [] * Take<[number, ...string[]], 2> equals [number, string] | [number] * Take<[...Date[], bigint], 2> equals [Date, Date] | [Date, bigint] | [bigint] * @example * Take<[0, 1, 2], 1 | 2> equals [0] | [0, 1] * Take<[0, 1, 2], number> equals [] | [0] | [0, 1] | [0, 1, 2] */ type Take<T extends readonly unknown[], N extends number> = Equals<T, any> extends true ? MaxLengthArray<N, any> : IsOneOf<N, [number, any]> extends true ? PrefixesOf<T>[number] : N extends N ? _Take<T, N> : never; type _Take<T extends readonly unknown[], N extends number, R extends readonly unknown[] = []> = R['length'] extends N ? R : T extends readonly [infer H, ...infer L] ? _Take<L, N, [...R, H]> : T extends readonly [] ? R : Subtract<N, R['length']> extends infer S extends number ? IsTuple<T> extends false ? [...R, ...MaxLengthArray<S, T[number]>] : IntegerRangeThrough<S> extends infer M extends number ? M extends M ? [ ...R, ...FixedLengthArray<M, DestructTuple<T>['rest'][0]>, ...Take<DestructTuple<T>['trailing'], Subtract<S, M>> ] : never : never : never; declare function take<const T extends readonly unknown[], const N extends number>(self: T, n: N): Take<T, N>; declare function take<T, N extends number>(self: Iterable<T>, n: N): MaxLengthArray<N, T>; /** * @example * Drop<[0, 1, 2], 0> equals [0, 1, 2] * Drop<[0, 1, 2], 1> equals [1, 2] * Drop<[0, 1, 2], 2> equals [2] * Drop<[0, 1, 2], 3> equals [] * Drop<[0, 1, 2], 4> equals [] * @example * Drop<[0, 1, 2], 1 | 2> equals [1, 2] | [2] * Drop<[0, 1, 2], number> equals [0, 1, 2] | [1, 2] | [2] | [] * @example * Drop<[number, ...string[]], 2> equals string[] * Drop<any, 1> equals any */ type Drop<T extends readonly unknown[], N extends number = 1> = N extends N ? number extends N ? _Drop<T, MaxLengthArray<T['length']>> : _Drop<T, FixedLengthArray<N>> : never; type _Drop<T extends readonly unknown[], N extends readonly unknown[]> = N extends readonly [any, ...infer NL] ? T extends readonly [any, ...infer TL] ? _Drop<TL, NL> : T extends readonly [...infer TL, infer H] ? Equals<TL[number], H> extends true ? _Drop<TL, NL> : T : T extends readonly [] ? [] : T : T; /** * Remove the first n elements from an array immutably. * If the second argument is omitted, it removes only one element. * * @example * drop([0, 1, 2]) returns [1, 2] * drop([0, 1, 2], 2) returns [2] * drop([0, 1, 2], 3) returns [] * @example * drop([0, 1, 2], 4) returns [] * drop([0, 1, 2], 0) returns [0, 1, 2] * drop([0, 1, 2], -1) returns [0, 1, 2] */ declare function drop<const T extends readonly unknown[]>(self: T): Drop<T>; declare function drop<const T extends readonly unknown[], N extends number>(self: T, n: N): Drop<T, N>; /** * @example * DropLast<[0, 1, 2], 0> equals [0, 1, 2] * DropLast<[0, 1, 2], 1> equals [0, 1] * DropLast<[0, 1, 2], 2> equals [0] * DropLast<[0, 1, 2], 3> equals [] * DropLast<[0, 1, 2], 4> equals [] * @example * DropLast<[0, 1, 2], 1 | 2> equals [0, 1] | [0] * DropLast<[0, 1, 2], number> equals [0, 1, 2] | [0, 1] | [0] | [] * @example * DropLast<[...number[], boolean], 2> equals number[] * DropLast<any, 1> equals any */ type DropLast<T extends readonly unknown[], N extends number = 1> = N extends N ? number extends N ? _DropLast<T, MaxLengthArray<T['length']>> : _DropLast<T, FixedLengthArray<N>> : never; type _DropLast<T extends readonly unknown[], N extends readonly unknown[]> = N extends readonly [any, ...infer NL] ? T extends readonly [...infer TL, any] ? _DropLast<TL, NL> : T extends readonly [] ? [] : T : T; /** * Remove the last n elements from an array immutably. * If the second argument is omitted, it removes only one element. * * @example * dropLast([0, 1, 2]) returns [0, 1] * dropLast([0, 1, 2], 2) returns [0] * dropLast([0, 1, 2], 3) returns [] * @example * dropLast([0, 1, 2], 4) returns [] * dropLast([0, 1, 2], 0) returns [0, 1, 2] * dropLast([0, 1, 2], -1) returns [0, 1, 2] */ declare function dropLast<const T extends readonly unknown[]>(self: T): Writable<DropLast<T, 1>>; declare function dropLast<const T extends readonly unknown[], const N extends number>(self: T, n: N): Writable<DropLast<T, N>>; declare function takeWhile<const T, const U extends T>(self: readonly T[], f: (_: T) => _ is U): U[]; declare function takeWhile<const T>(self: readonly T[], f: (_: T) => boolean): T[]; /** * @example * FirstOf<[bigint]> equals bigint * FirstOf<[number, bigint]> equals number * FirstOf<[]> equals undefined * FirstOf<boolean[]> equals boolean | undefined * FirstOf<[...string[], number]> equals string | number * @example * FirstOf<[Date] | [Date, boolean]> equals Date * FirstOf<[Date?, boolean?]> equals Date | boolean | undefined */ type FirstOf<T extends readonly unknown[]> = T extends readonly [infer First, ...any] ? First : T extends readonly [...infer U, infer Last] ? _FirstOf<U, Last> : T extends readonly [] ? undefined : T[number][] extends T ? T[number] | undefined : T extends readonly [(infer H)?, ...infer L] ? H | FirstOf<L> : never; type _FirstOf<T extends readonly unknown[], L> = T extends readonly [] ? L : T extends readonly [...infer T2, infer L2] ? _FirstOf<T2, L2> : T[0] | L; declare function firstOf<const T extends readonly unknown[]>(self: T): FirstOf<T>; /** * @example * LastOf<[bigint]> equals bigint * LastOf<[bigint, number]> equals number * LastOf<[]> equals undefined * LastOf<boolean[]> equals boolean | undefined * LastOf<[string, ...string[]]> equals string * LastOf<[boolean, ...string[]]> equals boolean | string * @example * LastOf<[Date] | [Date, boolean]> equals Date | boolean * LastOf<[Date?, boolean?]> equals Date | boolean | undefined */ type LastOf<T extends readonly unknown[]> = T extends readonly [...any, infer Last] ? Last : T extends readonly [] ? undefined : T extends readonly [infer H, ...infer L] ? _LastOf<H, L> : T[number][] extends T ? T[number] | undefined : T extends readonly [(infer H)?, ...infer L] ? H | LastOf<L> : T[0] | undefined; type _LastOf<H, L extends readonly unknown[]> = L extends readonly [] ? H : L extends readonly [infer H2, ...infer L2] ? _LastOf<H2, L2> : L[number][] extends L ? H | L[0] : L extends readonly [(infer H2)?, ...infer L2] ? _LastOf<H | H2, L2> : H | L[0]; declare function lastOf<const T extends readonly unknown[]>(self: T): LastOf<T>; /** * Improved version of {@link Array.prototype.indexOf}. * Returns undefined instead of -1 if not found. */ declare function indexOf<T>(self: readonly [], value: T, fromIndex?: number): undefined; declare function indexOf<T>(self: readonly T[], value: T, fromIndex?: number): number | undefined; declare function lastIndexOf<T>(self: readonly [], value: T, fromIndex?: number): undefined; declare function lastIndexOf<T>(self: readonly T[], value: T, fromIndex?: number): number | undefined; declare function indexesOf<T>(self: readonly [], value: T): []; declare function indexesOf<T>(self: readonly T[], value: T): number[]; declare function maxOf<const T>(self: ReadonlyNonEmptyArray<T>): T; declare function maxOf<T>(self: readonly T[]): T | undefined; declare function maxBy<const T, U>(self: ReadonlyNonEmptyArray<T>, by: (element: T) => U): T; declare function maxBy<T, U>(self: readonly T[], by: (element: T) => U): T | undefined; declare function minOf<const T>(self: ReadonlyNonEmptyArray<T>): T; declare function minOf<T>(self: readonly T[]): T | undefined; declare function minBy<const T, U>(self: ReadonlyNonEmptyArray<T>, by: (element: T) => U): T; declare function minBy<T, U>(self: readonly T[], by: (element: T) => U): T | undefined; declare function elementAt<T>(self: Iterable<T>, n: number): T | undefined; declare function modeOf<const T>(self: ReadonlyNonEmptyArray<T>): T; declare function modeOf<const T>(self: readonly T[]): T | undefined; declare function modeBy<const T, U>(self: ReadonlyNonEmptyArray<T>, by: (_: T) => U): T; declare function modeBy<T, U>(self: readonly T[], by: (_: T) => U): T | undefined; type NonEmptyArray<T = unknown> = [T, ...T[]] | [...T[], T]; type ReadonlyNonEmptyArray<T> = Readonly<NonEmptyArray<T>>; /** * @example * MinLengthArray<1> equals [unknown, ...unknown[]] | [...unknown[], unknown] * MinLengthArray<2, Date> equals [Date, Date, ...Date[]] | [Date, ...Date[], Date] | [...Date[], Date, Date] * MinLengthArray<0, string> equals string[] * MinLengthArray<number, string> equals string[] */ type MinLengthArray<N extends number, T = unknown> = _MinLengthArray<N, IntegerRangeThrough<N>, T>; type _MinLengthArray<N extends number, M extends number, T> = M extends M ? [...Drop<FixedLengthArray<N, T>, M>, ...T[], ...FixedLengthArray<M, T>] : never; type ReadonlyMinLengthArray<N extends number, T = unknown> = _ReadonlyMinLengthArray<N, IntegerRangeThrough<N>, T>; type _ReadonlyMinLengthArray<N extends number, M extends number, T> = M extends M ? readonly [...Drop<FixedLengthArray<N, T>, M>, ...T[], ...FixedLengthArray<M, T>] : never; declare function isMinLengthArray<T, N extends number>(self: T[], length: N): self is MinLengthArray<N, T>; declare function isMinLengthArray<T, N extends number>(self: readonly T[], length: N): self is ReadonlyMinLengthArray<N, T>; declare function isMinLengthArray<N extends number>(self: unknown, length: N): self is MinLengthArray<N>; declare const NON_EMPTY_MAP_TAG: unique symbol; type NonEmptyMap<K, T> = Branded<Map<K, T>, typeof NON_EMPTY_MAP_TAG>; type ReadonlyNonEmptyMap<K, T> = Branded<ReadonlyMap<K, T>, typeof NON_EMPTY_MAP_TAG>; /** * Create a Map object from a tuple of key-value pairs. * More precisely typed than Map constructor. * @example * mapOf([true, 1], [false, 0]) returns new Map([[true, 1], [false, 0]]) * mapOf([true, 1], [false, 0]) is typed as Map<boolean, number> * @example * mapOf() returns new Map() * mapOf() is typed as Map<never, never> */ declare function mapOf<T extends readonly (readonly [any, any])[]>(...args: T): Map<T[number][0], T[number][1]>; declare const NON_EMPTY_SET_TAG: unique symbol; type NonEmptySet<T> = Branded<Set<T>, typeof NON_EMPTY_SET_TAG>; type ReadonlyNonEmptySet<T> = Branded<ReadonlySet<T>, typeof NON_EMPTY_SET_TAG>; /** * setOf(...) is shorthand for new Set([...]). * Note that setOf() is Set<never> type, unlike new Set() being Set<unknown> type. * @example * setOf(121, 'abc') returns new Set([123, 'abc']) * setOf(121, 'abc') is typed as Set<number | string> * @example * setOf() returns new Set() * setOf() is typed as Set<never> */ declare function setOf(): Set<never>; declare function setOf<T extends readonly unknown[]>(...args: T): Set<T[number]>; /** * Add the given value to the set, but remove it if it is already included. * In other words, toggle the membership of the given value. * @example * toggleMembership(setOf(1, 2, 3), 2) returns setOf(1, 3) * toggleMembership(setOf(1, 2, 3), 4) returns setOf(1, 2, 3, 4) */ declare function toggleMembership<T, U>(self: ReadonlySet<T>, value: U): Set<T> | Set<T | U>; declare function setMembership<T, U>(self: ReadonlySet<T>, value: U, has: boolean): Set<T | U>; declare function has<T, U extends T>(self: ReadonlySet<U>, value: T): value is U; declare function has<T>(self: ReadonlySet<T>, value: T): boolean; /** * Create a union set. * @example * unionOf(setOf(1, 2, 3), setOf(2, 3, 4)) returns setOf(1, 2, 3, 4) * unionOf(setOf(1, 2, 3), setOf(2)) returns setOf(1, 2, 3) */ declare function unionOf<T, U>(lhs: ReadonlyNonEmptySet<T>, rhs: ReadonlySet<U>): NonEmptySet<T | U>; declare function unionOf<T, U>(lhs: ReadonlySet<T>, rhs: ReadonlyNonEmptySet<U>): NonEmptySet<T | U>; declare function unionOf<T, U>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): Set<T | U>; /** * Create an intersection set. * @example * intersectionOf(setOf(1, 2, 3), setOf(2, 3, 4)) returns setOf(2, 3) * intersectionOf(setOf(1, 2, 3), setOf(4, 5)) returns setOf() */ declare function intersectionOf<T, U extends T>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): Set<T>; declare function intersectionOf<T extends U, U>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): Set<U>; declare function intersectionOf<T>(lhs: ReadonlySet<T>, rhs: ReadonlySet<T>): Set<T>; declare function intersectionOf<T, U>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): Set<never>; /** * Create the set difference(lhs - rhs) that elements are contained lhs but not contained rhs. * @example * differenceOf(setOf(1, 2, 3), setOf(2, 3, 4)) returns setOf(1) */ declare function differenceOf<T, U>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): Set<T>; declare function isDisjoint<T, U>(lhs: ReadonlySet<T>, rhs: ReadonlySet<U>): boolean; /** isSubsetOf(a, b) means a ⊆ b. */ declare function isSubsetOf<T>(lhs: ReadonlySet<T>, rhs: ReadonlySet<T>): boolean; /** * @example * ToNumber<'00'> equals 0 * ToNumber<'001'> equals 1 * ToNumber<'-0'> equals 0 * ToNumber<'-00'> equals 0 * ToNumber<'-001'> equals -1 * ToNumber<'Infinity'> equals Infinity * ToNumber<'-Infinity'> equals -Infinity * @example * ToNumber<'1' | '2'> equals 1 | 2 * ToNumber<string> equals number * ToNumber<any> equals number * ToNumber<never> equals never * @example NaN is typed as number * ToNumber<'0xFF'> equals number * ToNumber<'1px'> equals number * ToNumber<''> equals number * ToNumber<' 12'> equals number * ToNumber<'1_234'> equals number * ToNumber<'1,234'> equals number */ type ToNumber<S extends string> = S extends 'Infinity' ? Infinity : S extends '-Infinity' ? NegativeInfinity : S extends `-${infer U}` ? RemoveLeadingExtraZeros<U> extends `${infer N extends number}` ? Negate<N> : number : RemoveLeadingExtraZeros<S> extends `${infer N extends number}` ? N : number; type RemoveLeadingExtraZeros<T extends string> = T extends `0${infer U extends Digit}${infer L}` ? RemoveLeadingExtraZeros<`${U}${L}`> : T; /** * @example * toNumber('123') returns 123 * toNumber('123') is typed as 123 * @example * toNumber('-1') returns -1 * toNumber('-1') is typed as -1 * @example * toNumber('01') returns 1 * toNumber('01') is typed as 1 * @example * toNumber('1.0') returns 1 * toNumber('1.0') is typed as number * @example * toNumber('1.05') returns 1.05 * toNumber('1.05') is typed as 1.05 */ declare function toNumber<const T extends string>(text: T): ToNumber<T>; type ToString<T> = T extends Interpolable ? `${T}` : string; declare function toString<const T>(value: T): ToString<T>; /** * A type for enabling automatic completion of specific literals in an editor. * Unlike a literal union type, it also accepts values other than the specified literals. * https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts */ type LiteralAutoComplete<Literals> = Literals | (ToBasePrimitiveType<Literals> & {}); /** The types that can be interpolated within a template literal. */ type Interpolable = string | number | bigint | boolean | null | undefined; type CharactersSubjectToRemoveByTrim = ' ' | '\t' | '\n' | '\r' | '\f' | '\v' | '\uFEFF' | '\xA0'; /** * @example * TrimStart<' abc '> equals 'abc ' * TrimStart<'\n\t\r\uFEFF\xA0'> equals '' */ type TrimStart<T extends string> = Equals<T, any> extends true ? string : T extends `${CharactersSubjectToRemoveByTrim}${infer L}` ? TrimStart<L> : T; /** * @example * trimStart(' abc ') returns 'abc ' * trimStart('\n\t\r\uFEFF\xA0') returns '' */ declare function trimStart<const T extends string>(self: T): TrimStart<T>; /** * @example * TrimEnd<' abc '> equals ' abc' * TrimEnd<'\n\t\r\uFEFF\xA0'> equals '' */ type TrimEnd<T extends string> = Equals<T, any> extends true ? string : T extends `${infer L}${CharactersSubjectToRemoveByTrim}` ? TrimEnd<L> : T; /** * @example * trimEnd(' abc ') returns ' abc' * trimEnd('\n\t\r\uFEFF\xA0') returns '' */ declare function trimEnd<const T extends string>(self: T): TrimEnd<T>; /** * @example * TrimStart<' abc '> equals 'abc' * TrimStart<'\n\t\r\uFEFF\xA0'> equals '' */ type Trim<T extends string> = TrimStart<TrimEnd<T>>; /** * @example * trim(' abc ') returns 'abc' * trim('\n\t\r\uFEFF\xA0') returns '' */ declare function trim<const T extends string>(self: T): Trim<T>; declare function map<T, U>(self: ReadonlyNonEmptyArray<T>, f: (_: T) => U): NonEmptyArray<U>; declare function map<T, U>(self: readonly T[], f: (_: T) => U): U[]; /** * @example * flatMap([0, 1, 2], (x) => [x, x + 0.5]) returns [0, 0.5, 1, 1.5, 2, 2.5] */ declare function flatMap<T>(self: readonly T[], f: (_: T) => readonly []): []; declare function flatMap<T, U>(self: readonly [], f: (_: T) => readonly U[]): []; declare function flatMap<T, U>(self: readonly T[], f: (_: T) => readonly U[]): U[]; declare function flatten<T>(self: readonly (readonly T[])[]): T[]; /** * @example * Join<['a', 'b', 'c']> equals 'a,b,c' * Join<['a', 'b', 'c'], ''> equals 'abc' * Join<['a', 'b', 'c'], '-' | '.'> equals 'a-b-c' | 'a.b.c' * Join<[], '.'> equals '' * @example * Join<[1, 2, 3], ' + '> equals '1 + 2 + 3' * Join<[Date, RegExp]> equals string */ type Join<T extends readonly unknown[], Separator extends string = ','> = Equals<T, any> extends true ? string : T extends readonly Interpolable[] ? _Join<T, Separator> : string; type _Join<T extends readonly Interpolable[], Separator extends string> = T extends readonly [ infer U extends Interpolable ] ? `${U}` : T extends readonly [infer H extends Interpolable, ...infer L extends readonly Interpolable[]] ? `${H}${Separator}${_Join<L, Separator>}` : T extends readonly [] ? '' : string; /** * @example * join(['a', 'b', 'c']) returns 'a,b,c' * join(['a', 'b', 'c'], '') returns 'abc' * join([1, 2, 3], ' + ') returns '1 + 2 + 3' */ declare function join<const T extends readonly unknown[], Separator extends string = ','>(self: T, separator?: Separator): Join<T, Separator>; /** * @example * Split<'12:34', ':'> equals ['12', '34'] * Split<'12:34:56', ':'> equals ['12', '34', '56'] * Split<'12:34', '@'> equals ['12:34'] * Split<'//', '/'> equals ['', '', ''] * Split<'12:34', ''> equals ['1', '2', ':', '3', '4'] * Split<`${number}:${number}`, ':'> equals [`${number}`, `${number}`] */ type Split<T extends string, Separator extends string> = string extends Separator ? string[] : Separator extends Separator ? T extends `${infer H}${Separator}${infer L}` ? `${Separator}${L}` extends '' ? [H] : [H, ...Split<L, Separator>] : [T] : never; /** * Note that when both arguments are empty strings, the return value differs from the standard split method. * @example * split('12:34', ':') returns ['12', '34'] * split('12:34', '') returns ['1', '2', ':', '3', '4'] * split('12:34', '@') returns ['12:34'] * split('', '') returns [''] */ declare function split<T extends string, Separator extends string>(self: T, separator: Separator): Split<T, Separator>; /** * @example * chunk([1, 2, 3, 4, 5, 6], 2) returns [[1, 2], [3, 4], [5, 6]] * chunk([1, 2, 3, 4, 5, 6], 2) is typed as [number, number][] * @example * chunk([3, 1, 4, 1, 5, 9, 2], 3) returns [[3, 1, 4], [1, 5, 9]] * chunk([3, 1, 4, 1, 5, 9, 2], 3) is typed as [number, number, number][] */ declare function chunk<T, N extends number>(array: readonly T[], size: N): number extends N ? T[][] : FixedLengthArray<N, T>[]; declare function padStart<T extends string>(self: T, length: number, value: string): string; declare function padEnd<T extends string>(self: T, length: number, value: string): string; declare function sort<const T extends readonly unknown[]>(self: T): FixedLengthArray<T['length'], T[number]>; declare function sortBy<const T extends readonly unknown[], U>(self: T, by: (_: T[number]) => U): FixedLengthArray<T['length'], T[number]>; /** * @example * Reverse<[0, 1, 2]> equals [2, 1, 0] * Reverse<[]> equals [] * Reverse<string[]> equals string[] * @example * Reverse<[0, 1] | [0, 1, 2]> equals [1, 0] | [2, 1, 0] * Reverse<[0, 1, ...number[], 9]> equals [9, ...number[], 1, 0] */ type Reverse<T extends readonly unknown[]> = [ ..._Reverse<DestructTuple<T>['trailing']>, ...DestructTuple<T>['rest'], ..._Reverse<Take<DestructTuple<T>['optional'], IntegerRangeThrough<DestructTuple<T>['optional']['length']>>>, ..._Reverse<DestructTuple<T>['leading']> ]; type _Reverse<T extends readonly unknown[]> = T extends readonly [infer First, ...infer R, infer Last] ? [Last, ..._Reverse<R>, First] : T extends readonly [infer First, ...infer R] ? [..._Reverse<R>, First] : T extends readonly [...infer R, infer Last] ? [Last, ..._Reverse<R>] : T extends readonly [] ? [] : T; declare function reverse<const T extends readonly unknown[]>(self: T): Reverse<T>; /** * @example * removeDuplicates(['a', 'b', 'a', 'c']) returns ['a', 'b', 'c'] * removeDuplicates([]) returns [] * removeDuplicates([undefined, null, null, null, undefined]) returns [undefined, null] */ declare function removeDuplicates<T>(self: readonly T[]): T[]; declare function removeDuplicatesBy<T, U>(self: readonly T[], by: (_: T) => U): T[]; /** * Generate the next sequential number starting from 0. * @example * [getNextSequentialNumber(), getNextSequentialNumber()] equals [0, 1] */ declare function getNextSequentialNumber(): number; /** * @example * SequentialNumbersUntil<3> equals [0, 1, 2] * SequentialNumbersUntil<2, 5> equals [2, 3, 4] * SequentialNumbersUntil<5, 2> equals [5, 4, 3] * SequentialNumbersUntil<7, 7> equals [] * @example * SequentialNumbersUntil<-3, 2> equals [-3, -2, -1, 0, 1] * SequentialNumbersUntil<3, -2> equals [3, 2, 1, 0, -1] * SequentialNumbersUntil<-1, -3> equals [-1, -2] * SequentialNumbersUntil<-3, -1> equals [-3, -2] * @example * SequentialNumbersUntil<2 | -2> equals [0, 1] | [0, -1] * SequentialNumbersUntil<1, 3 | 5> equals [1, 2] | [1, 2, 3, 4] * SequentialNumbersUntil<0 | 2, 4> equals [0, 1, 2, 3] | [2, 3] * SequentialNumbersUntil<number> equals number[] */ type SequentialNumbersUntil<From extends number, To extends number | OMITTED = OMITTED> = To extends number ? number extends From ? number[] : number extends To ? number[] : From extends From ? To extends To ? `${From}` extends `-${infer PN extends number}` ? `${To}` extends `-${infer PM extends number}` ? [...FixedLengthArray<PM>, ...any] extends [...FixedLengthArray<PN>, ...any] ? ToNegativeNumbers<Drop<NaturalNumbersUntil<PM>, PN>> : ToNegativeNumbers<Reverse<Drop<NaturalNumbersThrough<PN>, NaturalNumbersThrough<PM>['length']>>> : [...ToNegativeNumbers<Reverse<PositiveIntegersThrough<PN>>>, ...NaturalNumbersUntil<To>] : `${To}` extends `-${infer PM extends number}` ? [...Reverse<PositiveIntegersThrough<From>>, ...ToNegativeNumbers<NaturalNumbersUntil<PM>>] : [...FixedLengthArray<To>, ...any] extends [...FixedLengthArray<From>, ...any] ? Drop<NaturalNumbersUntil<To>, From> : Reverse<Drop<NaturalNumbersThrough<From>, NaturalNumbersThrough<To>['length']>> : never : never : SequentialNumbersUntil<0, From>; /** * @example * SequentialNumbersThrough<3> equals [0, 1, 2, 3] * SequentialNumbersThrough<2, 5> equals [2, 3, 4, 5] * SequentialNumbersThrough<5, 2> equals [5, 4, 3, 2] * SequentialNumbersThrough<7, 7> equals [7] * @example * SequentialNumbersThrough<-3, 2> equals [-3, -2, -1, 0, 1, 2] * SequentialNumbersThrough<3, -2> equals [3, 2, 1, 0, -1, -2] * SequentialNumbersThrough<-1, -3> equals [-1, -2, -3] * SequentialNumbersThrough<-3, -1> equals [-3, -2, -1] * @example * SequentialNumbersThrough<2 | -2> equals [0, 1, 2] | [0, -1, -2] * SequentialNumbersThrough<1, 3 | 5> equals [1, 2, 3] | [1, 2, 3, 4, 5] * SequentialNumbersThrough<0 | 2, 4> equals [0, 1, 2, 3, 4] | [2, 3, 4] * SequentialNumbersThrough<number> equals [number, ...number[]] | [...number[], number] */ type SequentialNumbersThrough<From extends number, To extends number | OMITTED = OMITTED> = To extends number ? number extends From ? NonEmptyArray<number> : number extends To ? NonEmptyArray<number> : From extends From ? To extends To ? `${From}` extends `-${infer PN extends number}` ? `${To}` extends `-${infer PM extends number}` ? [...FixedLengthArray<PM>, ...any] extends [...FixedLengthArray<PN>, ...any] ? ToNegativeNumbers<Drop<NaturalNumbersThrough<PM>, PN>> : ToNegativeNumbers<Reverse<Drop<NaturalNumbersThrough<PN>, PM>>> : [...ToNegativeNumbers<Reverse<PositiveIntegersThrough<PN>>>, ...NaturalNumbersThrough<To>] : `${To}` extends `-${infer PM extends number}` ? [...Reverse<PositiveIntegersThrough<From>>, ...ToNegativeNumbers<NaturalNumbersThrough<PM>>] : [...FixedLengthArray<To>, ...any] extends [...FixedLengthArray<From>, ...any] ? Drop<NaturalNumbersThrough<To>, From> : Reverse<Drop<NaturalNumbersThrough<From>, To>> : never : never : SequentialNumbersThrough<0, From>; /** * @example * NaturalNumbersUntil<3> equals [0, 1, 2] * NaturalNumbersUntil<0> equals [] * NaturalNumbersUntil<1 | 2> equals [0] | [0, 1] * NaturalNumbersUntil<number> equals number[] */ type NaturalNumbersUntil<N extends number> = number extends N ? number[] : N extends N ? Unlazy<_NaturalNumbersUntil<N, []>> : never; type _NaturalNumbersUntil<N extends number, Acc extends readonly unknown[]> = Acc['length'] extends N ? Acc : Lazy<_NaturalNumbersUntil<N, [...Acc, Acc['length']]>>; /** * @example * NaturalNumbersThrough<3> equals [0, 1, 2, 3] * NaturalNumbersThrough<0> equals [0] * NaturalNumbersThrough<1 | 2> equals [0, 1] | [0, 1, 2] * NaturalNumbersThrough<number> equals number[] */ type NaturalNumbersThrough<N extends number> = number extends N ? number[] : N extends N ? Unlazy<_NaturalNumbersThrough<FixedLengthArray<N>>> : never; type _NaturalNumbersThrough<Size extends readonly unknown[], R extends readonly unknown[] = []> = Size extends readonly [any, ...infer L extends readonly unknown[]] ? Lazy<_NaturalNumbersThrough<L, [Size['length'], ...R]>> : [0, ...R]; /** * @example * PositiveIntegersThrough<3> equals [1, 2, 3] * PositiveIntegersThrough<1 | 2> equals [1] | [1, 2] * PositiveIntegersThrough<0> equals [] * PositiveIntegersThrough<number> equals number[] */ type PositiveIntegersThrough<N extends number> = number extends N ? number[] : N extends 0 ? [] : N extends N ? _PositiveIntegersThrough<FixedLengthArray<N>> : never; type _PositiveIntegersThrough<Size extends readonly unknown[], R extends readonly unknown[] = []> = Size extends readonly [any, ...infer L] ? _PositiveIntegersThrough<L, [Size['length'], ...R]> : R; /** * @example * ToNegativeNumbers<[1, 2, -3]> equals [-1, -2, -3] * ToNegativeNumbers<[0]> equals [0] * ToNegativeNumbers<[]> equals [] */ type ToNegativeNumbers<T extends readonly number[]> = T extends readonly [ infer H extends number, ...infer L extends readonly number[] ] ? H extends 0 ? [0, ...ToNegativeNumbers<L>] : `-${H}` extends `${infer N extends number}` ? [N, ...ToNegativeNumbers<L>] : [H, ...ToNegativeNumbers<L>] : []; /** * @example * sequentialNumbersUntil(3) returns [0, 1, 2] * sequentialNumbersUntil(3) is typed as [0, 1, 2] * @example * sequentialNumbersUntil(0) returns [] * sequentialNumbersUntil(0) is typed as [] * @example * sequentialNumbersUntil(4 as number) returns [0, 1, 2, 3] * sequentialNumbersUntil(4 as number) is typed as number[] */ declare function sequentialNumbersUntil<To extends number>(to: To): SequentialNumbersUntil<To>; declare function sequentialNumbersUntil<From extends number, To extends number>(from: From, to: To): SequentialNumbersUntil<From, To>; /** * @example * sequentialNumbersThrough(3) returns [0, 1, 2, 3] * sequentialNumbersThrough(3) is typed as [0, 1, 2, 3] * @example * sequentialNumbersThrough(0) returns [0] * sequentialNumbersThrough(0) is typed as [0] * @example * sequentialNumbersThrough(4 as number) returns [0, 1, 2, 3, 4] * sequentialNumbersThrough(4 as number) is typed as number[] */ declare function sequentialNumbersThrough<To extends number>(to: To): SequentialNumbersThrough<To>; declare function sequentialNumbersThrough<From extends number, To extends number>(from: From, to: To): SequentialNumbersThrough<From, To>; /** * Generate an array of unique random natural numbers. * @example * uniqueRandomIntegersUntil(2, 2) returns [0, 1] or [1, 0] * uniqueRandomIntegersUntil(2, 1) returns [0] or [1] * uniqueRandomIntegersUntil(3, 1) returns [0] or [1] or [2] * uniqueRandomIntegersUntil(3, 2) returns [0, 1] or [0, 2] or [1, 0] or [1, 2] or [2, 0] or [2, 1] * @example * uniqueRandomIntegersUntil(2, 2) is typed as [0 | 1, 0 | 1] */ declare function uniqueRandomIntegersUntil<const N extends number, const M extends number>(upperBound: N, length: M): FixedLengthArray<M, IntegerRangeUntil<N>>; /** * @example * Repeat<3, ['a', 'b']> is typed as ['a', 'b', 'a', 'b', 'a', 'b'] * Repeat<0, ['a', 'b']> is typed as [] * @example * Repeat<0 | 1, ['a', 'b']> is typed as [] | ['a', 'b'] * Repeat<number, ['a', 'b']> is typed as ('a' | 'b')[] */ type Repeat<N extends number, A extends readonly unknown[]> = number extends N ? A[number][] : N extends N ? _Repeat<N, A> : never; type _Repeat<N extends number, A extends readonly unknown[], Size extends readonly unknown[] = [], R extends readonly unknown[] = []> = Size['length'] extends N ? R : _Repeat<N, A, [1, ...Size], [...R, ...A]>; /** * @example * RepeatString<'Abc', 2> equals 'AbcAbc' * RepeatString<'A', 0> equals '' * @example * RepeatString<'A' | 'B', 2> equals 'AA' | 'AB' | 'BA' | 'BB' * RepeatString<'A', 1 | 3> equals 'A' | 'AAA' * @example * RepeatString<string, 2> equals string * RepeatString<'A', number> equals string */ type RepeatString<S extends string, N extends number> = string extends S ? string : number extends N ? string : _RepeatString<S, FixedLengthArray<N>>; type _RepeatString<S extends string, Size extends readonly unknown[]> = Size extends [any, ...infer L] ? `${S}${_RepeatString<S, L>}` : ''; /** * @example * repeat(3, 'a') returns ['a', 'a', 'a'] * repeat(2, true, false) returns [true, false, true, false] */ declare function repeat<N extends number, const T extends readonly unknown[]>(count: N, ...values: T): Repeat<N, T>; declare function repeatApply<N extends number, T>(length: N, first: T, f: (_: T) => T): FixedLengthArray<N, T>; /** * Function that improves the type of Object.fromEntries. * * @example * fromEntries([['a', 1], ['b', 2]]) returns { a: 1, b: 2 } * fromEntries([['a', 1], ['b', 2]]) is typed as Record<'a' | 'b', 1 | 2> * @example * fromEntries([]) returns {} * fromEntries([]) is typed as Record<never, never> */ declare function fromEntries<const T extends readonly [any, any]>(entries: Iterable<T>): Record<T[0], T[1]>; /** * @example * IntegerRangeUntil<3> equals 0 | 1 | 2 * IntegerRangeUntil<4, 8> equals 4 | 5 | 6 | 7 * IntegerRangeUntil<5, 3> equals 5 | 4 * @example * IntegerRangeUntil<2, -2> equals 2 | 1 | 0 | -1 * IntegerRangeUntil<-2, 2> equals -2 | -1 | 0 | 1 * @example * IntegerRangeUntil<1, 1> equals never * IntegerRangeUntil<0> equals never * @example * IntegerRangeUntil<2 | 4> equals 0 | 1 | 2 | 3 * IntegerRangeUntil<number, 9> equals number * IntegerRangeUntil<9, number> equals number */ type IntegerRangeUntil<N extends number, M extends number | OMITTED = OMITTED> = N extends N ? M extends M ? IsOneOf<N, [number, any, Infinity, NegativeInfinity]> extends true ? number : M extends number ? `${N}` extends `-${infer PN extends number}` ? `${M}` extends `-${infer PM extends number}` ? [...FixedLengthArray<PN>, ...any] extends [...FixedLengthArray<PM>, ...any] ? Negate<Exclude<NaturalNumbersFrom0Through<PN>, NaturalNumbersFrom0Through<PM>>> : Negate<Exclude<NaturalNumbersFrom0Until<PM>, NaturalNumbersFrom0Until<PN>>> : Negate<NaturalNumbersFrom0Through<PN>> | NaturalNumbersFrom0Until<M> : `${M}` extends `-${infer PM extends number}` ? NaturalNumbersFrom0Through<N> | Negate<NaturalNumbersFrom0Until<PM>> : [...FixedLengthArray<N>, ...any] extends [...FixedLengthArray<M>, ...any] ? Exclude<NaturalNumbersFrom0Through<N>, NaturalNumbersFrom0Through<M>> : Exclude<NaturalNumbersFrom0Until<M>, NaturalNumbersFrom0Until<N>> : IntegerRangeUntil<0, N> : never : never; /** * @example * IntegerRangeThrough<3> equals 0 | 1 | 2 | 3 * IntegerRangeThrough<4, 8> equals 4 | 5 | 6 | 7 | 8 * IntegerRangeThrough<5, 3> equals 5 | 4 | 3 * @example * IntegerRangeThrough<2, -2> equals 2 | 1 | 0 | -1 | -2 * IntegerRangeThrough<-2, 2> equals -2 | -1 | 0 | 1 | 2 * @example * IntegerRangeThrough<1, 1> equals 1 * IntegerRangeThrough<0> equals 0 * @example * IntegerRangeThrough<2 | 4> equals 0 | 1 | 2 | 3 | 4 * IntegerRangeThrough<number, 9> equals number * IntegerRangeThrough<9, number> equals number */ type IntegerRangeThrough<N extends number, M extends number | OMITTED = OMITTED> = N extends N ? M extends M ? IsOneOf<N, [number, any, Infinity, NegativeInfinity]> extends true ? number : M extends number ? `${N}` extends `-${infer PN extends number}` ? `${M}` extends `-${infer PM extends number}` ? [...FixedLengthArray<PN>, ...any] extends [...FixedLengthArray<PM>, ...any] ? Negate<Exclude<NaturalNumbersFrom0Through<PN>, NaturalNumbersFrom0Until<PM>>> : Negate<Exclude<NaturalNumbersFrom0Through<PM>, NaturalNumbersFrom0Until<PN>>> : Negate<NaturalNumbersFrom0Through<PN>> | NaturalNumbersFrom0Through<M> : `${M}` extends `-${infer PM extends number}` ? NaturalNumbersFrom0Through<N> | Negate<NaturalNumbersFrom0Through<PM>> : [...FixedLengthArray<N>, ...any] extends [...FixedLengthArray<M>, ...any] ? Exclude<NaturalNumbersFrom0Through<N>, NaturalNumbersFrom0Until<M>> : Exclude<NaturalNumbersFrom0Through<M>, NaturalNumbersFrom0Until<N>> : IntegerRangeThrough<0, N> : never : never; type DigitToRangeUntil = { '0': never; '1': '0'; '2': '0' | '1'; '3': '0' | '1' | '2'; '4': '0' | '1' | '2' | '3'; '5': '0' | '1' | '2' | '3' | '4'; '6': '0' | '1' | '2' | '3' | '4' | '5'; '7': '0' | '1' | '2' | '3' | '4' | '5' | '6'; '8': '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'; '9': '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8'; }; /** * Generate a union type from 0 to the given number minus 1. It's orders of magnitude faster compared to a naive implementation. * @example * NaturalNumbersFrom0Until<0> equals never * NaturalNumbersFrom0Until<1> equals 0 * NaturalNumbersFrom0Until<2> equals 0 | 1 * NaturalNumbersFrom0Until<10000> equals 0 | 1 | 2 | ... | 9999 */ type NaturalNumbersFrom0Until<N extends number> = ToNumber<_NaturalNumbersFrom0Until<ToDigitArray<N>>>; type _NaturalNumbersFrom0Until<DigitArray extends readonly Digit[]> = DigitArray extends readonly [ infer D extends Digit ] ? `${DigitToRangeUntil[D]}` : DigitArray extends readonly [infer H extends Digit, ...infer L extends readonly Digit[]] ? `${DigitToRangeUntil[H]}${RepeatString<Digit, L['length']> extends infer S extends string ? S : never}` | `${H}${_NaturalNumbersFrom0Until<L>}` : ''; /** * Generate a union type from 0 to the given number. It's orders of magnitude faster compared to a naive implementation. * @example * NaturalNumbersFrom0Through<0> equals 0 * NaturalNumbersFrom0Through<1> equals 1 * NaturalNumbersFrom0Through<2> equals 0 | 1 | 2 * NaturalNumbersFrom0Through<10000> equals 0 | 1 | 2 | ... | 10000 */ type NaturalNumbersFrom0Through<N extends number> = NaturalNumbersFrom0Until<N> | N; /** * Determine if the given value is in the given range. * @example * isInIntegerRangeUntil(50, 0, 100) returns true * isInIntegerRangeUntil(101, 0, 100) returns false * @example */ declare function isInIntegerRangeUntil<N extends number, M extends number>(value: number, n: N, m: M): value is IntegerRangeUntil<N, M>; declare function isInIntegerRangeThrough<N extends number, M extends number>(value: number, n: N, m: M): value is IntegerRangeThrough<N, M>; /** * @example * randomIntegerUntil(3) returns 0, 1 or 2 * randomIntegerUntil(3) is typed as 0 | 1 | 2 * randomIntegerUntil(1, 4) returns 1, 2 or 3 * randomIntegerUntil(1, 4) is typed as 1 | 2 | 3 * @example * randomIntegerUntil(-2) returns 0 or -1 * randomIntegerUntil(-2) is typed as 0 | -1 * @example * randomIntegerUntil(0) throws RangeError * randomIntegerUntil(0) is typed as never * randomIntegerUntil(5, 5) throws RangeError * randomIntegerUntil(5, 5) is typed as never */ declare function randomIntegerUntil<To extends number>(to: To): IntegerRangeUntil<To>; declare function randomIntegerUntil<From extends number, To extends number>(from: From, to: To): IntegerRangeUntil<From, To>; declare function randomIntegerThrough<N extends number>(end: N): IntegerRangeThrough<N>; declare function randomIntegerThrough<N extends number, M extends number>(start: N, end: M): IntegerRangeThrough<N, M>; type Infinity = 1e999; declare const Infinity: Infinity; type NegativeInfinity = -1e999; declare const NegativeInfinity: NegativeInfinity; /** * @example * IsInteger<12.34> equals false * IsInteger<-12> equals true * IsInteger<1.2e-15> equals fa