@stryke/types
Version:
A package containing many base TypeScript type definitions that are shared across many projects.
124 lines (122 loc) • 7.39 kB
text/typescript
import { BuildTuple, IsEqual } from "./base.cjs";
import { IsNegative, NegativeInfinity, PositiveInfinity } from "./number.cjs";
import { StringLength, StringToNumber } from "./string.cjs";
//#region src/logic.d.ts
/**
* Returns a boolean for whether A is false.
*
* @example
* ```
* Not<true>;
* //=> false
*
* Not<false>;
* //=> true
* ```
*/
type Not<A extends boolean> = A extends true ? false : A extends false ? true : never;
/**
* Returns a boolean for whether the given `boolean` is not `false`.
*/
type IsNotFalse<T extends boolean> = [T] extends [false] ? false : true;
type Or<A extends boolean, B extends boolean> = [A, B][number] extends false ? false : true extends [IsEqual<A, true>, IsEqual<B, true>][number] ? true : never;
type And<A extends boolean, B extends boolean> = [A, B][number] extends true ? true : true extends [IsEqual<A, false>, IsEqual<B, false>][number] ? false : never;
/**
* Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both positive numeric characters.
*
* @example
* ```
* PositiveNumericCharacterGt<'5', '1'>;
* //=> true
*
* PositiveNumericCharacterGt<'1', '1'>;
* //=> false
* ```
*/
type PositiveNumericCharacterGt<A extends string, B extends string> = NumericString extends `${infer HeadA}${A}${infer _TailA}` ? NumericString extends `${infer HeadB}${B}${infer _TailB}` ? HeadA extends `${HeadB}${infer _}${infer __}` ? true : false : never : never;
/**
* Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both numeric strings and have the same length.
*
* @example
* ```
* SameLengthPositiveNumericStringGt<'50', '10'>;
* //=> true
*
* SameLengthPositiveNumericStringGt<'10', '10'>;
* //=> false
* ```
*/
type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}` ? B extends `${infer FirstB}${infer RestB}` ? FirstA extends FirstB ? SameLengthPositiveNumericStringGt<RestA, RestB> : PositiveNumericCharacterGt<FirstA, FirstB> : never : false;
type NumericString = "0123456789";
/**
* Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
*
* @example
* ```
* PositiveNumericStringGt<'500', '1'>;
* //=> true
*
* PositiveNumericStringGt<'1', '1'>;
* //=> false
*
* PositiveNumericStringGt<'1', '500'>;
* //=> false
* ```
*/
type PositiveNumericStringGt<A extends string, B extends string> = A extends B ? false : [BuildTuple<StringLength<A>, 0>, BuildTuple<StringLength<B>, 0>] extends infer R extends [readonly unknown[], readonly unknown[]] ? R[0] extends [...R[1], ...infer Remain extends readonly unknown[]] ? 0 extends Remain["length"] ? SameLengthPositiveNumericStringGt<A, B> : true : false : never;
type LessThan<A extends number, B extends number> = number extends A | B ? never : GreaterThanOrEqual<A, B> extends true ? false : true;
type GreaterThan<A extends number, B extends number> = number extends A | B ? never : [IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>, IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>] extends infer R extends [boolean, boolean, boolean, boolean] ? Or<And<IsEqual<R[0], true>, IsEqual<R[2], false>>, And<IsEqual<R[3], true>, IsEqual<R[1], false>>> extends true ? true : Or<And<IsEqual<R[1], true>, IsEqual<R[3], false>>, And<IsEqual<R[2], true>, IsEqual<R[0], false>>> extends true ? false : true extends R[number] ? false : [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean] ? [true, false] extends R ? false : [false, true] extends R ? true : [false, false] extends R ? PositiveNumericStringGt<`${A}`, `${B}`> : PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`> : never : never;
type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B ? never : A extends B ? true : GreaterThan<A, B>;
/**
* Returns the minimum value from a tuple of integers.
*
* Note:
* - Float numbers are not supported.
*
* @example
* ```
* ArrayMin<[1, 2, 5, 3]>;
* //=> 1
*
* ArrayMin<[1, 2, 5, 3, -5]>;
* //=> -5
* ```
*/
type ArrayMin<A extends number[], Result extends number = PositiveInfinity> = number extends A[number] ? never : A extends [infer F extends number, ...infer R extends number[]] ? LessThan<F, Result> extends true ? ArrayMin<R, F> : ArrayMin<R, Result> : Result;
/**
* Returns the maximum value from a tuple of integers.
*
* Note:
* - Float numbers are not supported.
*
* @example
* ```
* ArrayMax<[1, 2, 5, 3]>;
* //=> 5
*
* ArrayMax<[1, 2, 5, 3, 99, -1]>;
* //=> 99
* ```
*/
type ArrayMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number] ? never : A extends [infer F extends number, ...infer R extends number[]] ? GreaterThan<F, Result> extends true ? ArrayMax<R, F> : ArrayMax<R, Result> : Result;
/**
* Returns the absolute value of a given value.
*
* @example
* ```
* NumberAbsolute<-1>;
* //=> 1
*
* NumberAbsolute<1>;
* //=> 1
*
* NumberAbsolute<NegativeInfinity>
* //=> PositiveInfinity
* ```
*/
type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
type Subtract<A extends number, B extends number> = number extends A | B ? number : [IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>, IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>] extends infer R extends [boolean, boolean, boolean, boolean] ? Or<And<IsEqual<R[0], true>, IsEqual<R[2], false>>, And<IsEqual<R[3], true>, IsEqual<R[1], false>>> extends true ? PositiveInfinity : Or<And<IsEqual<R[1], true>, IsEqual<R[3], false>>, And<IsEqual<R[2], true>, IsEqual<R[0], false>>> extends true ? NegativeInfinity : true extends R[number] ? number : [IsNegative<A>, IsNegative<B>] extends infer R ? [false, false] extends R ? BuildTuple<A> extends infer _R ? R extends [...BuildTuple<B>, ...infer R] ? R["length"] : number : never : LessThan<A, B> extends true ? number : [false, true] extends R ? Sum<A, NumberAbsolute<B>> : Subtract<NumberAbsolute<B>, NumberAbsolute<A>> : never : never;
type Sum<A extends number, B extends number> = number extends A | B ? number : [IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>, IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>] extends infer R extends [boolean, boolean, boolean, boolean] ? Or<And<IsEqual<R[0], true>, IsEqual<R[3], false>>, And<IsEqual<R[2], true>, IsEqual<R[1], false>>> extends true ? PositiveInfinity : Or<And<IsEqual<R[1], true>, IsEqual<R[2], false>>, And<IsEqual<R[3], true>, IsEqual<R[0], false>>> extends true ? NegativeInfinity : true extends R[number] ? number : ([IsNegative<A>, IsNegative<B>] extends infer R ? [false, false] extends R ? [...BuildTuple<A>, ...BuildTuple<B>]["length"] : [true, true] extends R ? number : ArrayMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_ ? ArrayMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number ? Max_ extends A | B ? Subtract<Max_, Min_> : number : never : never : never) & number : never;
//#endregion
export { And, ArrayMax, ArrayMin, GreaterThan, GreaterThanOrEqual, IsNotFalse, LessThan, Not, NumberAbsolute, Or, PositiveNumericCharacterGt, PositiveNumericStringGt, SameLengthPositiveNumericStringGt, Subtract, Sum };
//# sourceMappingURL=logic.d.cts.map