// ============================================================================ // Helpers // ============================================================================ // Internal helper to build array of specified length type InternalBuildArray< N extends number, Acc extends readonly unknown[] = [], > = Acc["length"] extends N ? Acc : InternalBuildArray // ============================================================================ // Primitives // ============================================================================ /** * @description Get the sign of a number (-1 for negative, 0 for zero, 1 for positive). * * @example * ``` * // Expect: 1 * type Example1 = NumberSign<5> * // Expect: -1 * type Example2 = NumberSign<-5> * // Expect: 0 * type Example3 = NumberSign<0> * ``` */ export type NumberSign = N extends 0 ? 0 : NumberIsNegative extends true ? -1 : 1 /** * @description Get the number of digits in a positive integer. * * @example * ``` * // Expect: 1 * type Example1 = NumberDigitCount<5> * // Expect: 3 * type Example2 = NumberDigitCount<123> * // Expect: 1 * type Example3 = NumberDigitCount<0> * ``` */ export type NumberDigitCount = NumberAbs extends infer AbsN extends number ? `${AbsN}` extends `${infer Digits}` ? Digits["length"] : never : never // ============================================================================ // Validation // ============================================================================ /** * @description Check if a number is zero. * * @example * ``` * // Expect: true * type Example1 = NumberIsZero<0> * // Expect: false * type Example2 = NumberIsZero<1> * // Expect: false * type Example3 = NumberIsZero<-1> * ``` */ export type NumberIsZero = N extends 0 ? true : false /** * @description Check if a number is positive (greater than zero). * * @example * ``` * // Expect: true * type Example1 = NumberIsPositive<1> * // Expect: true * type Example2 = NumberIsPositive<100> * // Expect: false * type Example3 = NumberIsPositive<0> * // Expect: false * type Example4 = NumberIsPositive<-1> * ``` */ export type NumberIsPositive = `${N}` extends `-${string}` ? false : N extends 0 ? false : true /** * @description Check if a number is negative (less than zero). * * @example * ``` * // Expect: true * type Example1 = NumberIsNegative<-1> * // Expect: true * type Example2 = NumberIsNegative<-100> * // Expect: false * type Example3 = NumberIsNegative<0> * // Expect: false * type Example4 = NumberIsNegative<1> * ``` */ export type NumberIsNegative = `${N}` extends `-${string}` ? true : false /** * @description Check if a number is even. * * @example * ``` * // Expect: true * type Example1 = NumberIsEven<0> * // Expect: true * type Example2 = NumberIsEven<2> * // Expect: true * type Example3 = NumberIsEven<10> * // Expect: false * type Example4 = NumberIsEven<1> * // Expect: false * type Example5 = NumberIsEven<3> * ``` */ export type NumberIsEven = `${N}` extends `${string}${"0" | "2" | "4" | "6" | "8"}` ? true : false /** * @description Check if a number is odd. * * @example * ``` * // Expect: true * type Example1 = NumberIsOdd<1> * // Expect: true * type Example2 = NumberIsOdd<3> * // Expect: false * type Example3 = NumberIsOdd<0> * // Expect: false * type Example4 = NumberIsOdd<2> * ``` */ export type NumberIsOdd = `${N}` extends `${string}${"1" | "3" | "5" | "7" | "9"}` ? true : false /** * @description Check if two numbers are equal. * * @example * ``` * // Expect: true * type Example1 = NumberIsEqual<5, 5> * // Expect: false * type Example2 = NumberIsEqual<5, 10> * // Expect: true * type Example3 = NumberIsEqual<0, 0> * ``` */ export type NumberIsEqual = A extends B ? B extends A ? true : false : false /** * @description Check if a number is a power of 2. * * @example * ``` * // Expect: true * type Example1 = NumberIsPowerOfTwo<1> * // Expect: true * type Example2 = NumberIsPowerOfTwo<8> * // Expect: false * type Example3 = NumberIsPowerOfTwo<6> * ``` */ export type NumberIsPowerOfTwo = N extends 0 ? false : N extends 1 ? true : NumberIsEven extends true ? NumberIsPowerOfTwo> : false // ============================================================================ // Comparison // ============================================================================ /** * @description Check if A is greater than B. * * @example * ``` * // Expect: true * type Example1 = NumberGreaterThan<5, 3> * // Expect: false * type Example2 = NumberGreaterThan<3, 5> * // Expect: false * type Example3 = NumberGreaterThan<5, 5> * ``` */ export type NumberGreaterThan = InternalBuildArray extends [...InternalBuildArray, ...infer Rest] ? Rest extends [unknown, ...unknown[]] ? true : false : false /** * @description Check if A is greater than or equal to B. * * @example * ``` * // Expect: true * type Example1 = NumberGreaterThanOrEqual<5, 3> * // Expect: false * type Example2 = NumberGreaterThanOrEqual<3, 5> * // Expect: true * type Example3 = NumberGreaterThanOrEqual<5, 5> * ``` */ export type NumberGreaterThanOrEqual = NumberIsEqual extends true ? true : NumberGreaterThan /** * @description Check if A is less than B. * * @example * ``` * // Expect: true * type Example1 = NumberLessThan<3, 5> * // Expect: false * type Example2 = NumberLessThan<5, 3> * // Expect: false * type Example3 = NumberLessThan<5, 5> * ``` */ export type NumberLessThan = NumberGreaterThan /** * @description Check if A is less than or equal to B. * * @example * ``` * // Expect: true * type Example1 = NumberLessThanOrEqual<3, 5> * // Expect: false * type Example2 = NumberLessThanOrEqual<5, 3> * // Expect: true * type Example3 = NumberLessThanOrEqual<5, 5> * ``` */ export type NumberLessThanOrEqual = NumberIsEqual extends true ? true : NumberLessThan // ============================================================================ // Manipulation // ============================================================================ /** * @description Add two numbers (limited by TypeScript's recursion depth). * * @example * ``` * // Expect: 5 * type Example1 = NumberAdd<2, 3> * // Expect: 10 * type Example2 = NumberAdd<7, 3> * // Expect: 0 * type Example3 = NumberAdd<0, 0> * ``` */ export type NumberAdd = [ ...InternalBuildArray, ...InternalBuildArray, ]["length"] extends infer Sum ? Sum extends number ? Sum : never : never /** * @description Subtract B from A (limited by TypeScript's recursion depth). * * @example * ``` * // Expect: 2 * type Example1 = NumberSubtract<5, 3> * // Expect: 0 * type Example2 = NumberSubtract<3, 3> * // Expect: 10 * type Example3 = NumberSubtract<15, 5> * ``` */ export type NumberSubtract = InternalBuildArray extends [...InternalBuildArray, ...infer Rest] ? Rest["length"] : never type InternalNumberMultiply< A extends number, B extends number, Acc extends readonly unknown[] = [], > = B extends 0 ? Acc["length"] : InternalNumberMultiply, [...Acc, ...InternalBuildArray]> /** * @description Multiply two numbers (limited by TypeScript's recursion depth). * * @example * ``` * // Expect: 6 * type Example1 = NumberMultiply<2, 3> * // Expect: 0 * type Example2 = NumberMultiply<5, 0> * // Expect: 25 * type Example3 = NumberMultiply<5, 5> * ``` */ export type NumberMultiply = InternalNumberMultiply extends number ? InternalNumberMultiply : never type InternalNumberDivide< A extends number, B extends number, Quotient extends readonly unknown[] = [], > = NumberGreaterThanOrEqual extends true ? InternalNumberDivide, B, [...Quotient, unknown]> : Quotient["length"] /** * @description Divide A by B (integer division, limited by TypeScript's recursion depth). * * @example * ``` * // Expect: 2 * type Example1 = NumberDivide<6, 3> * // Expect: 3 * type Example2 = NumberDivide<10, 3> * // Expect: 5 * type Example3 = NumberDivide<25, 5> * ``` */ export type NumberDivide = B extends 0 ? never : InternalNumberDivide extends number ? InternalNumberDivide : never type InternalNumberModulo = NumberGreaterThanOrEqual extends true ? InternalNumberModulo, B> : A /** * @description Get the remainder of A divided by B (modulo operation). * * @example * ``` * // Expect: 0 * type Example1 = NumberModulo<6, 3> * // Expect: 1 * type Example2 = NumberModulo<10, 3> * // Expect: 2 * type Example3 = NumberModulo<5, 3> * ``` */ export type NumberModulo = B extends 0 ? never : InternalNumberModulo type InternalNumberPower< Base extends number, Exponent extends number, Acc extends number = 1, > = Exponent extends 0 ? Acc : InternalNumberPower, NumberMultiply> /** * @description Calculate Base raised to the power of Exponent. * * @example * ``` * // Expect: 8 * type Example1 = NumberPower<2, 3> * // Expect: 1 * type Example2 = NumberPower<5, 0> * // Expect: 25 * type Example3 = NumberPower<5, 2> * ``` */ export type NumberPower = InternalNumberPower extends number ? InternalNumberPower : never /** * @description Get the absolute value of a number. * * @example * ``` * // Expect: 5 * type Example1 = NumberAbs<5> * // Expect: 5 * type Example2 = NumberAbs<-5> * // Expect: 0 * type Example3 = NumberAbs<0> * ``` */ export type NumberAbs = `${N}` extends `-${infer Positive extends number}` ? Positive : N /** * @description Negate a number (multiply by -1). * * @example * ``` * // Expect: -5 * type Example1 = NumberNegate<5> * // Expect: 5 * type Example2 = NumberNegate<-5> * // Expect: 0 * type Example3 = NumberNegate<0> * ``` */ export type NumberNegate = N extends 0 ? 0 : `${N}` extends `-${infer Positive extends number}` ? Positive : `-${N}` extends `${infer Negative extends number}` ? Negative : never /** * @description Increment a number by 1. * * @example * ``` * // Expect: 1 * type Example1 = NumberIncrement<0> * // Expect: 6 * type Example2 = NumberIncrement<5> * // Expect: 11 * type Example3 = NumberIncrement<10> * ``` */ export type NumberIncrement = NumberAdd /** * @description Decrement a number by 1. * * @example * ``` * // Expect: 4 * type Example1 = NumberDecrement<5> * // Expect: 9 * type Example2 = NumberDecrement<10> * // Expect: 0 * type Example3 = NumberDecrement<1> * ``` */ export type NumberDecrement = NumberSubtract type InternalNumberSum = T extends [ infer First extends number, ...infer Rest extends number[], ] ? InternalNumberSum> : Acc /** * @description Calculate the sum of all numbers in a tuple. * * @example * ``` * // Expect: 10 * type Example1 = NumberSum<[1, 2, 3, 4]> * // Expect: 0 * type Example2 = NumberSum<[]> * // Expect: 5 * type Example3 = NumberSum<[5]> * ``` */ export type NumberSum = InternalNumberSum extends number ? InternalNumberSum : never type InternalNumberProduct = T extends [ infer First extends number, ...infer Rest extends number[], ] ? InternalNumberProduct> : Acc /** * @description Calculate the product of all numbers in a tuple. * * @example * ``` * // Expect: 24 * type Example1 = NumberProduct<[1, 2, 3, 4]> * // Expect: 1 * type Example2 = NumberProduct<[]> * // Expect: 0 * type Example3 = NumberProduct<[5, 0, 3]> * ``` */ export type NumberProduct = InternalNumberProduct extends number ? InternalNumberProduct : never /** * @description Calculate the average of all numbers in a tuple (integer division). * * @example * ``` * // Expect: 2 * type Example1 = NumberAverage<[1, 2, 3, 4]> * // Expect: 5 * type Example2 = NumberAverage<[5, 5, 5]> * // Expect: 3 * type Example3 = NumberAverage<[2, 3, 5]> * ``` */ export type NumberAverage = T extends [] ? never : NumberDivide, T["length"]> type InternalNumberFactorial = N extends 0 ? Acc : InternalNumberFactorial, NumberMultiply> /** * @description Calculate the factorial of a number (N!). * * @example * ``` * // Expect: 1 * type Example1 = NumberFactorial<0> * // Expect: 1 * type Example2 = NumberFactorial<1> * // Expect: 120 * type Example3 = NumberFactorial<5> * ``` */ export type NumberFactorial = InternalNumberFactorial extends number ? InternalNumberFactorial : never type InternalNumberFibonacci< N extends number, Current extends number = 0, Next extends number = 1, Counter extends number = 0, > = Counter extends N ? Current : InternalNumberFibonacci, NumberIncrement> /** * @description Get the Nth Fibonacci number (0-indexed). * * @example * ``` * // Expect: 0 * type Example1 = NumberFibonacci<0> * // Expect: 1 * type Example2 = NumberFibonacci<1> * // Expect: 5 * type Example3 = NumberFibonacci<5> * ``` */ export type NumberFibonacci = InternalNumberFibonacci extends number ? InternalNumberFibonacci : never type InternalNumberGCD = B extends 0 ? A : InternalNumberGCD> /** * @description Calculate the greatest common divisor (GCD) of two numbers. * * @example * ``` * // Expect: 6 * type Example1 = NumberGCD<12, 18> * // Expect: 1 * type Example2 = NumberGCD<7, 3> * // Expect: 5 * type Example3 = NumberGCD<15, 5> * ``` */ export type NumberGCD = InternalNumberGCD extends number ? InternalNumberGCD : never /** * @description Calculate the least common multiple (LCM) of two numbers. * * @example * ``` * // Expect: 12 * type Example1 = NumberLCM<3, 4> * // Expect: 36 * type Example2 = NumberLCM<12, 18> * // Expect: 15 * type Example3 = NumberLCM<5, 3> * ``` */ export type NumberLCM = NumberDivide< NumberMultiply, NumberGCD > type InternalNumberRange< From extends number, To extends number, Acc extends number[] = [], > = From extends To ? [...Acc, From] : NumberLessThan extends true ? InternalNumberRange, To, [...Acc, From]> : InternalNumberRange, To, [...Acc, From]> /** * @description Generate a range of numbers from From to To (inclusive). * * @example * ``` * // Expect: [1, 2, 3, 4, 5] * type Example1 = NumberRange<1, 5> * // Expect: [0, 1, 2] * type Example2 = NumberRange<0, 2> * // Expect: [5, 4, 3] * type Example3 = NumberRange<5, 3> * ``` */ export type NumberRange = InternalNumberRange /** * @description Get the minimum value from a tuple of numbers. * * @example * ``` * // Expect: 1 * type Example1 = NumberMin<[3, 1, 4, 2]> * // Expect: 0 * type Example2 = NumberMin<[5, 0, 10]> * // Expect: 5 * type Example3 = NumberMin<[5]> * ``` */ export type NumberMin = T extends [ infer First extends number, ...infer Rest extends number[], ] ? Rest extends [] ? First : NumberMin extends infer RestMin extends number ? NumberLessThan extends true ? First : RestMin : never : never /** * @description Get the maximum value from a tuple of numbers. * * @example * ``` * // Expect: 4 * type Example1 = NumberMax<[3, 1, 4, 2]> * // Expect: 10 * type Example2 = NumberMax<[5, 0, 10]> * // Expect: 5 * type Example3 = NumberMax<[5]> * ``` */ export type NumberMax = T extends [ infer First extends number, ...infer Rest extends number[], ] ? Rest extends [] ? First : NumberMax extends infer RestMax extends number ? NumberGreaterThan extends true ? First : RestMax : never : never /** * @description Clamp a number between a minimum and maximum value. * * @example * ``` * // Expect: 5 * type Example1 = NumberClamp<3, 5, 10> * // Expect: 7 * type Example2 = NumberClamp<7, 5, 10> * // Expect: 10 * type Example3 = NumberClamp<15, 5, 10> * ``` */ export type NumberClamp = NumberLessThan extends true ? Min : NumberGreaterThan extends true ? Max : Value // ============================================================================ // Number Conversion // ============================================================================ /** * @description Convert a number to a string literal type. * * @example * ``` * // Expect: '5' * type Example1 = NumberToString<5> * // Expect: '0' * type Example2 = NumberToString<0> * // Expect: '-10' * type Example3 = NumberToString<-10> * ``` */ export type NumberToString = `${N}` /** * @description Convert a number to a boolean (0 = false, non-zero = true). * * @example * ``` * // Expect: false * type Example1 = NumberToBoolean<0> * // Expect: true * type Example2 = NumberToBoolean<5> * // Expect: true * type Example3 = NumberToBoolean<-3> * ``` */ export type NumberToBoolean = N extends 0 ? false : true