import type { CoercibleToString } from './string.js'; import type { Subtract, SubtractBigInt } from './type-math.js'; import type { ExpandRecursively, Falsy, UnionToTuple } from './types.js'; /** @internal @hidden */ export interface _EQ { result: 'equal'; } /** @internal @hidden */ export interface _NEQ { result: 'not-equal'; } interface GenericResult { type?: string; result: string; } /** @internal @hidden */ export interface _StringUnknownSubstring { result: 'substring'; before: string; after: string; add: boolean; } /** @internal @hidden */ export type _StringUnknown = _StringUnknownSubstring | _EQ | _NEQ; export type String = string extends To ? _StringUnknown : string extends From ? _StringUnknown : To extends From ? _EQ : To extends `${infer Before}${From}${infer After}` ? { result: 'substring'; before: Before; after: After; add: true; } : From extends `${infer Before}${To}${infer After}` ? { result: 'substring'; before: Before; after: After; add: false; } : { result: 'not-equal'; }; export declare function string(from: From, to: To): String; /** @internal @hidden */ export interface _NumberUnknownDiff { type: 'number'; result: 'diff'; value: number; } /** @internal @hidden */ export type _NumberUnknown = _NumberUnknownDiff | (_NEQ & { type: 'number'; }); /** * Diff two numbers. * `not-equal` is only returned when encountering `NaN` or infinite values */ export type Number = number extends To ? _NumberUnknown : number extends From ? _NumberUnknown : To extends From ? _EQ & { type: 'number'; } : { result: 'diff'; type: 'number'; value: Subtract; }; export declare function number(from: From, to: To): Number; /** @internal @hidden */ export interface _BigIntUnknown { type: 'bigint'; result: 'diff'; value: bigint; } export type BigInt = bigint extends From ? _BigIntUnknown : bigint extends To ? _BigIntUnknown : From extends To ? _EQ & { type: 'bigint'; } : { type: 'bigint'; result: 'diff'; value: SubtractBigInt; }; export declare function bigint(from: From, to: To): BigInt; /** @internal @hidden */ export interface _BooleanUnknown { type: 'boolean'; result: 'equal' | 'not-equal'; } export type Boolean = boolean extends From ? _BooleanUnknown : boolean extends To ? _BooleanUnknown : { type: 'boolean'; } & (From extends To ? _EQ : _NEQ); export declare function boolean(from: From, to: To): Boolean; type fn = (...args: unknown[]) => unknown; /** @internal @hidden */ export interface _FunctionUnknownDiff { type: 'function'; result: 'diff'; return: GenericResult; args: _ArrayUnknown; } /** @internal @hidden */ type _FunctionUnknown = _FunctionUnknownDiff | (_NEQ & { type: 'function'; }) | (_EQ & { type: 'function'; }); /** @internal @hidden */ export interface _FunctionType { type: 'function'; result: 'diff'; return: Deep, ReturnType>; args: Array, Parameters>; } export type FunctionType = fn extends From ? _FunctionUnknown : fn extends To ? _FunctionUnknown : From extends To ? To extends From ? _EQ & { type: 'function'; } : _FunctionType : _FunctionType; /** @internal @hidden */ export interface _FunctionRTArgDiff { type: 'function'; result: 'diff-arg'; argCount: number; } type _FunctionRTUnknown = _FunctionRTArgDiff | (_EQ & { type: 'function'; }); export type FunctionRT = fn extends From ? _FunctionRTUnknown : fn extends To ? _FunctionRTUnknown : Parameters['length'] extends Parameters['length'] ? _EQ & { type: 'function'; } : { type: 'function'; result: 'diff-arg'; argCount: Subtract['length'], Parameters['length']>; }; export declare function functionRT(from: From, to: To): FunctionRT; interface _ArrayUnknownDiff { type: 'array'; result: 'diff'; elements: number; changed: GenericResult[]; } type _ArrayUnknown = _ArrayUnknownDiff | { type: 'array'; result: 'equal'; }; interface _ArrayDiff, To extends ArrayLike> { type: 'array'; result: 'diff'; elements: Subtract; changed: { [K in keyof From & keyof To & number]: Deep; }[keyof From & keyof To & number]; } export type Array, To extends ArrayLike> = ArrayLike extends From ? _ArrayUnknown : ArrayLike extends To ? _ArrayUnknown : number extends From['length'] ? _ArrayUnknown : number extends To['length'] ? _ArrayUnknown : From['length'] extends To['length'] ? { [K in keyof From & keyof To & number]: Deep['result']; }[keyof From & keyof To & number] extends 'equal' ? { type: 'array'; result: 'equal'; } : _ArrayDiff : _ArrayDiff; export declare function array, To extends ArrayLike>(from: From, to: To): Array; interface _ObjectUnknownDiff { type: 'object'; result: 'diff'; removed: string[]; added: string[]; changed: Record; } type _ObjectUnknown = _ObjectUnknownDiff | ({ type: 'object'; } & _EQ); interface _ObjectDiff { type: 'object'; result: 'diff'; removed: Exclude extends never ? [] : UnionToTuple>; added: Exclude extends never ? [] : UnionToTuple>; changed: { [K in keyof From & keyof To]: Deep; }; } export type Object = object extends From ? _ObjectUnknown : object extends To ? _ObjectUnknown : From extends To ? To extends From ? { type: 'object'; result: 'equal'; } : _ObjectDiff : _ObjectDiff; export declare function object(from: From, to: To): Object; interface NotComparable { result: 'not-comparable'; } type DeepCommon = unknown extends From ? GenericResult : unknown extends To ? GenericResult : From extends string ? To extends CoercibleToString ? String & { type: 'string'; coerced: To extends string ? false : true; } : NotComparable : From extends number ? To extends number ? Number & { coerced: false; } : To extends bigint ? `${To}` extends `${infer V extends number}` ? Number & { coerced: true; } : never & 'error: bigint -> number' : NotComparable : From extends bigint ? To extends bigint ? BigInt & { coerced: false; } : To extends number ? `${To}` extends `${infer V extends bigint}` ? BigInt & { coerced: true; } : never & 'error: number -> bigint' : NotComparable : From extends boolean ? To extends boolean | Falsy ? Boolean & { coerced: To extends boolean ? false : true; } : NotComparable : From extends symbol ? To extends symbol ? { type: 'symbol'; result: symbol extends To ? 'equal' | 'not-equal' : symbol extends From ? 'equal' | 'not-equal' : To extends From ? 'equal' : 'not-equal'; } : NotComparable : From extends undefined ? To extends undefined | Falsy ? { result: 'equal'; type: 'undefined'; coerced: To extends undefined ? false : true; } : NotComparable : From extends null ? To extends null | Falsy ? { result: 'equal'; type: 'null'; coerced: To extends null ? false : true; } : NotComparable : From extends ArrayLike ? To extends ArrayLike ? Array : NotComparable : From extends object ? To extends undefined | null ? NotComparable : To extends object ? Object : NotComparable : NotComparable; export type DeepRT = From extends fn ? To extends fn ? FunctionRT : NotComparable : DeepCommon; export type Deep = From extends fn ? To extends fn ? FunctionType : NotComparable : DeepCommon; interface GenericDeepResult extends GenericResult { coerced?: boolean; } export declare function deep(from: From, to: To): ExpandRecursively> & GenericDeepResult; export {};