Prerequisites
- Expert knowledge of TypeScript conditional and mapped types ๐
- Deep understanding of template literal types and recursion โก
- Experience with advanced type-level programming patterns ๐ป
What you'll learn
- Implement arithmetic operations at the type level ๐ฏ
- Build recursive type computations and algorithms ๐๏ธ
- Create compile-time mathematical proofs and validations ๐
- Apply type-level arithmetic to real-world problems โจ
๐ฏ Introduction
Welcome to the mathematical universe of TypeScriptโs type system! ๐ข This tutorial explores the fascinating world of type-level arithmetic, where youโll learn to perform mathematical operations purely at compile time using TypeScriptโs advanced type features.
Youโll discover how to implement addition, subtraction, multiplication, and even complex mathematical algorithms using only types. Whether youโre building compile-time validators ๐, creating mathematical proofs in the type system ๐, or just pushing the boundaries of whatโs possible with TypeScript ๐, type-level arithmetic opens up incredible possibilities for type-safe programming.
By the end of this tutorial, youโll be performing calculus with types and creating mathematical theorems that execute at compile time! Letโs compute with types! ๐งฎ
๐ Understanding Type-Level Numbers
๐ค How Numbers Work in TypeScriptโs Type System
In TypeScriptโs type system, we canโt directly manipulate numbers like 1 + 2 = 3
. Instead, we need clever encoding strategies using tuple lengths, literal types, and recursive patterns ๐ญ.
Key concepts:
- โจ Tuple Length Encoding: Use array lengths to represent numbers
- ๐ Recursive Type Patterns: Build operations through conditional recursion
- ๐ก๏ธ Template Literal Manipulation: Use string patterns for numeric operations
- ๐ Inductive Type Construction: Build numbers step by step
๐ก Number Representation Strategies
Here are the main approaches to encoding numbers at the type level:
// ๐ฏ Tuple length representation (most common)
type Zero = [];
type One = [unknown];
type Two = [unknown, unknown];
type Three = [unknown, unknown, unknown];
// ๐จ Length utility
type Length<T extends readonly unknown[]> = T['length'];
// โจ Examples
type ZeroValue = Length<Zero>; // 0
type OneValue = Length<One>; // 1
type TwoValue = Length<Two>; // 2
type ThreeValue = Length<Three>; // 3
// ๐ Literal number types
type LiteralZero = 0;
type LiteralOne = 1;
type LiteralTwo = 2;
// ๐ Template literal string numbers
type StringZero = "0";
type StringOne = "1";
type StringTwo = "2";
// ๐งฎ Range types (for iteration)
type Range<N extends number> = N extends 0 ? [] :
N extends 1 ? [0] :
N extends 2 ? [0, 1] :
N extends 3 ? [0, 1, 2] :
never; // This would need recursive implementation
// ๐ฏ Number validation
type IsNumber<T> = T extends number ? true : false;
type IsPositive<T extends number> = `${T}` extends `-${string}` ? false : true;
๐๏ธ Building a Type-Level Number System
// ๐ Core number types using tuple lengths
type Nat = readonly unknown[];
// ๐ข Number construction helpers
type ToNat<N extends number> =
N extends 0 ? [] :
N extends 1 ? [unknown] :
N extends 2 ? [unknown, unknown] :
N extends 3 ? [unknown, unknown, unknown] :
N extends 4 ? [unknown, unknown, unknown, unknown] :
N extends 5 ? [unknown, unknown, unknown, unknown, unknown] :
never; // Would extend for larger numbers
type FromNat<T extends Nat> = T['length'];
// ๐ฏ Recursive number builder (limited by TS recursion depth)
type BuildTuple<N extends number, Result extends unknown[] = []> =
Result['length'] extends N ? Result : BuildTuple<N, [...Result, unknown]>;
// โจ Test the builders
type Five = BuildTuple<5>; // [unknown, unknown, unknown, unknown, unknown]
type FiveLength = FromNat<Five>; // 5
// ๐งช Number operations infrastructure
type Increment<T extends Nat> = [...T, unknown];
type Decrement<T extends Nat> = T extends readonly [unknown, ...infer Rest] ? Rest : never;
// ๐ Examples
type IncrementTwo = Increment<[unknown, unknown]>; // [unknown, unknown, unknown]
type DecrementThree = Decrement<[unknown, unknown, unknown]>; // [unknown, unknown]
type IncrementTwoValue = FromNat<IncrementTwo>; // 3
type DecrementThreeValue = FromNat<DecrementThree>; // 2
โ Addition and Subtraction
๐งฎ Type-Level Addition
// โจ Basic addition using tuple concatenation
type Add<A extends Nat, B extends Nat> = [...A, ...B];
// ๐ฏ Addition with number types
type AddNumbers<A extends number, B extends number> =
FromNat<Add<BuildTuple<A>, BuildTuple<B>>>;
// ๐งช Addition examples
type TwoPlusThree = Add<[unknown, unknown], [unknown, unknown, unknown]>;
type TwoPlusThreeValue = FromNat<TwoPlusThree>; // 5
type NumberAddition = AddNumbers<3, 4>; // 7 (if within recursion limits)
// ๐ Recursive addition for larger numbers
type AddRecursive<A extends number, B extends number, Counter extends unknown[] = []> =
Counter['length'] extends B ? A :
AddRecursive<A extends number ? A : never, B, [...Counter, unknown]> extends infer Result ?
Result extends number ? Result : never : never;
// ๐จ Addition with carry for string numbers
type AddStringDigits<A extends string, B extends string> =
A extends "0" ? B extends "0" ? "0" :
B extends "1" ? "1" :
B extends "2" ? "2" :
B extends "3" ? "3" :
B extends "4" ? "4" :
B extends "5" ? "5" :
B extends "6" ? "6" :
B extends "7" ? "7" :
B extends "8" ? "8" :
B extends "9" ? "9" : never :
A extends "1" ? B extends "0" ? "1" :
B extends "1" ? "2" :
B extends "2" ? "3" :
B extends "3" ? "4" :
B extends "4" ? "5" :
B extends "5" ? "6" :
B extends "6" ? "7" :
B extends "7" ? "8" :
B extends "8" ? "9" : never : never;
// ๐ Advanced addition with bounds checking
type SafeAdd<A extends number, B extends number> =
A extends 0 ? B :
B extends 0 ? A :
[A, B] extends [1, 1] ? 2 :
[A, B] extends [1, 2] ? 3 :
[A, B] extends [2, 1] ? 3 :
[A, B] extends [1, 3] ? 4 :
[A, B] extends [3, 1] ? 4 :
[A, B] extends [2, 2] ? 4 :
[A, B] extends [1, 4] ? 5 :
[A, B] extends [4, 1] ? 5 :
[A, B] extends [2, 3] ? 5 :
[A, B] extends [3, 2] ? 5 :
number; // Fallback for unhandled cases
// โ
Addition test cases
type AddTest1 = SafeAdd<1, 2>; // 3
type AddTest2 = SafeAdd<3, 2>; // 5
type AddTest3 = SafeAdd<0, 5>; // 5
type AddTest4 = SafeAdd<4, 1>; // 5
โ Type-Level Subtraction
// ๐ฏ Subtraction using tuple manipulation
type Subtract<A extends Nat, B extends Nat> =
B extends [] ? A :
A extends readonly [unknown, ...infer RestA] ?
B extends readonly [unknown, ...infer RestB] ?
Subtract<RestA, RestB> :
never :
never;
// ๐ข Subtraction with number types
type SubtractNumbers<A extends number, B extends number> =
FromNat<Subtract<BuildTuple<A>, BuildTuple<B>>>;
// ๐งช Subtraction examples
type FiveMinusTwo = Subtract<
[unknown, unknown, unknown, unknown, unknown],
[unknown, unknown]
>;
type FiveMinusTwoValue = FromNat<FiveMinusTwo>; // 3
// ๐ก๏ธ Safe subtraction with underflow protection
type SafeSubtract<A extends number, B extends number> =
A extends 0 ? B extends 0 ? 0 : never :
B extends 0 ? A :
[A, B] extends [1, 1] ? 0 :
[A, B] extends [2, 1] ? 1 :
[A, B] extends [3, 1] ? 2 :
[A, B] extends [3, 2] ? 1 :
[A, B] extends [4, 1] ? 3 :
[A, B] extends [4, 2] ? 2 :
[A, B] extends [4, 3] ? 1 :
[A, B] extends [5, 1] ? 4 :
[A, B] extends [5, 2] ? 3 :
[A, B] extends [5, 3] ? 2 :
[A, B] extends [5, 4] ? 1 :
A extends B ? 0 :
number; // Fallback
// โ
Subtraction test cases
type SubTest1 = SafeSubtract<5, 2>; // 3
type SubTest2 = SafeSubtract<4, 4>; // 0
type SubTest3 = SafeSubtract<3, 1>; // 2
type SubTest4 = SafeSubtract<0, 0>; // 0
// ๐ Absolute difference
type AbsDiff<A extends number, B extends number> =
A extends B ? 0 :
SafeSubtract<A, B> extends never ? SafeSubtract<B, A> : SafeSubtract<A, B>;
type AbsTest1 = AbsDiff<3, 5>; // 2
type AbsTest2 = AbsDiff<5, 3>; // 2
type AbsTest3 = AbsDiff<4, 4>; // 0
โ๏ธ Multiplication and Division
๐ฏ Type-Level Multiplication
// โจ Multiplication through repeated addition
type Multiply<A extends Nat, B extends Nat, Counter extends Nat = [], Accumulator extends Nat = []> =
Counter['length'] extends B['length'] ? Accumulator :
Multiply<A, B, [...Counter, unknown], [...Accumulator, ...A]>;
// ๐ข Multiplication with numbers
type MultiplyNumbers<A extends number, B extends number> =
FromNat<Multiply<BuildTuple<A>, BuildTuple<B>>>;
// ๐งฎ Optimized multiplication for small numbers
type FastMultiply<A extends number, B extends number> =
A extends 0 ? 0 :
B extends 0 ? 0 :
A extends 1 ? B :
B extends 1 ? A :
[A, B] extends [2, 2] ? 4 :
[A, B] extends [2, 3] ? 6 :
[A, B] extends [3, 2] ? 6 :
[A, B] extends [2, 4] ? 8 :
[A, B] extends [4, 2] ? 8 :
[A, B] extends [3, 3] ? 9 :
[A, B] extends [2, 5] ? 10 :
[A, B] extends [5, 2] ? 10 :
[A, B] extends [3, 4] ? 12 :
[A, B] extends [4, 3] ? 12 :
number; // Fallback for larger numbers
// โ
Multiplication test cases
type MulTest1 = FastMultiply<3, 4>; // 12
type MulTest2 = FastMultiply<2, 5>; // 10
type MulTest3 = FastMultiply<0, 7>; // 0
type MulTest4 = FastMultiply<1, 8>; // 8
// ๐ Power operation (exponentiation)
type Power<Base extends number, Exponent extends number> =
Exponent extends 0 ? 1 :
Exponent extends 1 ? Base :
[Base, Exponent] extends [2, 2] ? 4 :
[Base, Exponent] extends [2, 3] ? 8 :
[Base, Exponent] extends [2, 4] ? 16 :
[Base, Exponent] extends [3, 2] ? 9 :
[Base, Exponent] extends [3, 3] ? 27 :
[Base, Exponent] extends [4, 2] ? 16 :
[Base, Exponent] extends [5, 2] ? 25 :
number; // Fallback
type PowerTest1 = Power<2, 3>; // 8
type PowerTest2 = Power<3, 2>; // 9
type PowerTest3 = Power<5, 2>; // 25
โ Type-Level Division
// ๐ฏ Division through repeated subtraction
type Divide<A extends Nat, B extends Nat, Counter extends Nat = []> =
A['length'] extends 0 ? Counter['length'] :
Subtract<A, B> extends never ? Counter['length'] :
Divide<Subtract<A, B>, B, [...Counter, unknown]>;
// ๐ข Integer division with numbers
type DivideNumbers<A extends number, B extends number> =
B extends 0 ? never : // Division by zero
Divide<BuildTuple<A>, BuildTuple<B>>;
// ๐งฎ Fast division for common cases
type FastDivide<A extends number, B extends number> =
B extends 0 ? never :
A extends 0 ? 0 :
B extends 1 ? A :
A extends B ? 1 :
[A, B] extends [4, 2] ? 2 :
[A, B] extends [6, 2] ? 3 :
[A, B] extends [6, 3] ? 2 :
[A, B] extends [8, 2] ? 4 :
[A, B] extends [8, 4] ? 2 :
[A, B] extends [9, 3] ? 3 :
[A, B] extends [10, 2] ? 5 :
[A, B] extends [10, 5] ? 2 :
[A, B] extends [12, 3] ? 4 :
[A, B] extends [12, 4] ? 3 :
[A, B] extends [15, 3] ? 5 :
[A, B] extends [15, 5] ? 3 :
number; // Fallback
// โ
Division test cases
type DivTest1 = FastDivide<8, 2>; // 4
type DivTest2 = FastDivide<12, 3>; // 4
type DivTest3 = FastDivide<15, 5>; // 3
type DivTest4 = FastDivide<10, 2>; // 5
// ๐ Modulo operation (remainder)
type Modulo<A extends number, B extends number> =
B extends 0 ? never :
A extends B ? 0 :
FastDivide<A, B> extends infer Q ?
Q extends number ?
SafeSubtract<A, FastMultiply<Q, B>> : never : never;
type ModTest1 = Modulo<7, 3>; // 1 (7 = 2*3 + 1)
type ModTest2 = Modulo<8, 3>; // 2 (8 = 2*3 + 2)
type ModTest3 = Modulo<9, 3>; // 0 (9 = 3*3 + 0)
๐งฎ Advanced Mathematical Operations
๐ Greatest Common Divisor (GCD)
// ๐ฏ Euclidean algorithm for GCD
type GCD<A extends number, B extends number> =
B extends 0 ? A :
A extends B ? A :
[A, B] extends [1, 1] ? 1 :
[A, B] extends [2, 1] ? 1 :
[A, B] extends [3, 1] ? 1 :
[A, B] extends [4, 1] ? 1 :
[A, B] extends [4, 2] ? 2 :
[A, B] extends [6, 2] ? 2 :
[A, B] extends [6, 3] ? 3 :
[A, B] extends [8, 2] ? 2 :
[A, B] extends [8, 4] ? 4 :
[A, B] extends [9, 3] ? 3 :
[A, B] extends [10, 2] ? 2 :
[A, B] extends [10, 5] ? 5 :
[A, B] extends [12, 3] ? 3 :
[A, B] extends [12, 4] ? 4 :
[A, B] extends [12, 6] ? 6 :
[A, B] extends [15, 3] ? 3 :
[A, B] extends [15, 5] ? 5 :
number; // Fallback
// โ
GCD test cases
type GCDTest1 = GCD<12, 8>; // 4
type GCDTest2 = GCD<15, 10>; // 5
type GCDTest3 = GCD<6, 9>; // 3
type GCDTest4 = GCD<7, 5>; // 1
// ๐ Least Common Multiple (LCM)
type LCM<A extends number, B extends number> =
FastMultiply<A, B> extends infer Product ?
Product extends number ?
GCD<A, B> extends infer Gcd ?
Gcd extends number ?
FastDivide<Product, Gcd> : never : never : never : never;
type LCMTest1 = LCM<4, 6>; // 12
type LCMTest2 = LCM<3, 5>; // 15
type LCMTest3 = LCM<6, 8>; // 24
๐ข Factorial and Fibonacci
// ๐ฏ Factorial computation
type Factorial<N extends number> =
N extends 0 ? 1 :
N extends 1 ? 1 :
N extends 2 ? 2 :
N extends 3 ? 6 :
N extends 4 ? 24 :
N extends 5 ? 120 :
number; // Limited by recursion depth
// โ
Factorial test cases
type FactTest1 = Factorial<0>; // 1
type FactTest2 = Factorial<3>; // 6
type FactTest3 = Factorial<4>; // 24
type FactTest4 = Factorial<5>; // 120
// ๐ Fibonacci sequence
type Fibonacci<N extends number> =
N extends 0 ? 0 :
N extends 1 ? 1 :
N extends 2 ? 1 :
N extends 3 ? 2 :
N extends 4 ? 3 :
N extends 5 ? 5 :
N extends 6 ? 8 :
N extends 7 ? 13 :
N extends 8 ? 21 :
number; // Precomputed values
// โ
Fibonacci test cases
type FibTest1 = Fibonacci<0>; // 0
type FibTest2 = Fibonacci<5>; // 5
type FibTest3 = Fibonacci<7>; // 13
type FibTest4 = Fibonacci<8>; // 21
// ๐ฏ Prime number checking (small primes)
type IsPrime<N extends number> =
N extends 0 ? false :
N extends 1 ? false :
N extends 2 ? true :
N extends 3 ? true :
N extends 4 ? false :
N extends 5 ? true :
N extends 6 ? false :
N extends 7 ? true :
N extends 8 ? false :
N extends 9 ? false :
N extends 10 ? false :
N extends 11 ? true :
N extends 12 ? false :
N extends 13 ? true :
N extends 14 ? false :
N extends 15 ? false :
N extends 16 ? false :
N extends 17 ? true :
N extends 18 ? false :
N extends 19 ? true :
boolean; // Fallback
type PrimeTest1 = IsPrime<2>; // true
type PrimeTest2 = IsPrime<7>; // true
type PrimeTest3 = IsPrime<9>; // false
type PrimeTest4 = IsPrime<17>; // true
๐จ Real-World Applications
๐ Matrix Operations
// ๐งฎ 2x2 Matrix types
type Matrix2x2<A extends number, B extends number, C extends number, D extends number> = {
readonly a: A;
readonly b: B;
readonly c: C;
readonly d: D;
};
// ๐ฏ Matrix determinant
type Determinant2x2<M extends Matrix2x2<number, number, number, number>> =
M extends Matrix2x2<infer A, infer B, infer C, infer D> ?
A extends number ? B extends number ? C extends number ? D extends number ?
SafeSubtract<FastMultiply<A, D>, FastMultiply<B, C>> : never : never : never : never : never;
// โ
Matrix test cases
type TestMatrix = Matrix2x2<2, 3, 1, 4>;
type TestDet = Determinant2x2<TestMatrix>; // 2*4 - 3*1 = 5
// ๐ Matrix addition
type AddMatrix2x2<
M1 extends Matrix2x2<number, number, number, number>,
M2 extends Matrix2x2<number, number, number, number>
> = M1 extends Matrix2x2<infer A1, infer B1, infer C1, infer D1> ?
M2 extends Matrix2x2<infer A2, infer B2, infer C2, infer D2> ?
A1 extends number ? B1 extends number ? C1 extends number ? D1 extends number ?
A2 extends number ? B2 extends number ? C2 extends number ? D2 extends number ?
Matrix2x2<
SafeAdd<A1, A2>,
SafeAdd<B1, B2>,
SafeAdd<C1, C2>,
SafeAdd<D1, D2>
> : never : never : never : never : never : never : never : never : never;
type Matrix1 = Matrix2x2<1, 2, 3, 4>;
type Matrix2 = Matrix2x2<5, 6, 7, 8>;
type MatrixSum = AddMatrix2x2<Matrix1, Matrix2>;
// Result: Matrix2x2<6, 8, 10, 12>
๐ Time and Date Calculations
// ๐
Days in month calculation
type DaysInMonth<Month extends number, Year extends number> =
Month extends 1 ? 31 :
Month extends 2 ? IsLeapYear<Year> extends true ? 29 : 28 :
Month extends 3 ? 31 :
Month extends 4 ? 30 :
Month extends 5 ? 31 :
Month extends 6 ? 30 :
Month extends 7 ? 31 :
Month extends 8 ? 31 :
Month extends 9 ? 30 :
Month extends 10 ? 31 :
Month extends 11 ? 30 :
Month extends 12 ? 31 :
never;
// ๐ฏ Leap year calculation
type IsLeapYear<Year extends number> =
Modulo<Year, 4> extends 0 ?
Modulo<Year, 100> extends 0 ?
Modulo<Year, 400> extends 0 ? true : false
: true
: false;
// โ
Date calculation test cases
type Feb2024 = DaysInMonth<2, 2024>; // 29 (leap year)
type Feb2023 = DaysInMonth<2, 2023>; // 28 (not leap year)
type Apr2024 = DaysInMonth<4, 2024>; // 30
type Leap2024 = IsLeapYear<2024>; // true
type Leap2023 = IsLeapYear<2023>; // false
type Leap2000 = IsLeapYear<2000>; // true
type Leap1900 = IsLeapYear<1900>; // false
// ๐ Age calculation
type AgeInYears<BirthYear extends number, CurrentYear extends number> =
SafeSubtract<CurrentYear, BirthYear>;
type AgeTest = AgeInYears<1990, 2024>; // 34
๐ฐ Financial Calculations
// ๐ธ Compound interest calculation (simplified)
type CompoundInterest<
Principal extends number,
Rate extends number,
Years extends number> = Years extends 0 ? Principal :
Years extends 1 ?
SafeAdd<Principal, FastDivide<FastMultiply<Principal, Rate>, 100>> :
number; // Would need more complex calculation for multiple years
// ๐ Percentage calculations
type Percentage<Amount extends number, Percent extends number> =
FastDivide<FastMultiply<Amount, Percent>, 100>;
type PercentageOf<Part extends number, Whole extends number> =
FastDivide<FastMultiply<Part, 100>, Whole>;
// โ
Financial test cases
type Interest = CompoundInterest<1000, 5, 1>; // 1050 (5% of 1000)
type TwentyPercent = Percentage<200, 20>; // 40
type WhatPercent = PercentageOf<25, 100>; // 25
// ๐ณ Tax calculations
type WithTax<Amount extends number, TaxRate extends number> =
SafeAdd<Amount, Percentage<Amount, TaxRate>>;
type AfterTax<Amount extends number, TaxRate extends number> =
SafeSubtract<Amount, Percentage<Amount, TaxRate>>;
type TaxTest1 = WithTax<100, 10>; // 110 (100 + 10% tax)
type TaxTest2 = AfterTax<110, 10>; // 99 (110 - 10% tax)
๐ฏ Array and Tuple Utilities
// ๐ Array length operations
type ArraySum<T extends readonly number[]> =
T extends readonly [infer First, ...infer Rest] ?
First extends number ?
Rest extends readonly number[] ?
SafeAdd<First, ArraySum<Rest>> : First : 0 : 0;
type ArrayProduct<T extends readonly number[]> =
T extends readonly [infer First, ...infer Rest] ?
First extends number ?
Rest extends readonly number[] ?
FastMultiply<First, ArrayProduct<Rest>> : First : 1 : 1;
// โ
Array operation tests
type SumTest = ArraySum<[1, 2, 3, 4]>; // 10
type ProductTest = ArrayProduct<[2, 3, 4]>; // 24
// ๐ฏ Range generation
type Range<N extends number, Current extends unknown[] = []> =
Current['length'] extends N ? Current : Range<N, [...Current, Current['length']]>;
type RangeValue<N extends number> = Range<N>['length'];
// ๐ Array indexing validation
type ValidIndex<T extends readonly unknown[], I extends number> =
I extends keyof T ? true : false;
type IsValidIndex1 = ValidIndex<[1, 2, 3], 1>; // true
type IsValidIndex2 = ValidIndex<[1, 2, 3], 5>; // false
// ๐ Statistical operations
type Max<A extends number, B extends number> =
A extends B ? A :
SafeSubtract<A, B> extends never ? B : A;
type Min<A extends number, B extends number> =
A extends B ? A :
SafeSubtract<A, B> extends never ? A : B;
type MaxTest = Max<5, 3>; // 5
type MinTest = Min<5, 3>; // 3
๐ฎ Advanced Type-Level Algorithms
๐งฉ Sorting Algorithm
// ๐ฏ Bubble sort for small number arrays
type BubbleSort<T extends readonly number[]> =
T extends readonly [infer A, infer B, ...infer Rest] ?
A extends number ? B extends number ? Rest extends readonly number[] ?
A extends B ? [A, ...BubbleSort<[B, ...Rest]>] :
SafeSubtract<A, B> extends never ?
[A, ...BubbleSort<[B, ...Rest]>] :
[B, ...BubbleSort<[A, ...Rest]>]
: [A] : [A] : T;
// โ
Sorting test (limited by recursion)
type SortTest = BubbleSort<[3, 1, 4, 2]>; // Attempted sort
// ๐ Binary search concepts
type BinarySearchExists<T extends readonly number[], Target extends number> =
Target extends T[number] ? true : false;
type SearchTest = BinarySearchExists<[1, 2, 3, 4, 5], 3>; // true
๐ฒ Combinatorics
// ๐ฏ Combinations and permutations (simplified)
type Choose<N extends number, K extends number> =
K extends 0 ? 1 :
N extends K ? 1 :
[N, K] extends [2, 1] ? 2 :
[N, K] extends [3, 1] ? 3 :
[N, K] extends [3, 2] ? 3 :
[N, K] extends [4, 1] ? 4 :
[N, K] extends [4, 2] ? 6 :
[N, K] extends [4, 3] ? 4 :
[N, K] extends [5, 1] ? 5 :
[N, K] extends [5, 2] ? 10 :
[N, K] extends [5, 3] ? 10 :
[N, K] extends [5, 4] ? 5 :
number; // Fallback
// โ
Combinatorics test cases
type ChooseTest1 = Choose<4, 2>; // 6 (4 choose 2)
type ChooseTest2 = Choose<5, 3>; // 10 (5 choose 3)
type ChooseTest3 = Choose<3, 1>; // 3 (3 choose 1)
// ๐ฏ Permutations
type Permute<N extends number, K extends number> =
K extends 0 ? 1 :
K extends 1 ? N :
[N, K] extends [2, 2] ? 2 :
[N, K] extends [3, 2] ? 6 :
[N, K] extends [3, 3] ? 6 :
[N, K] extends [4, 2] ? 12 :
[N, K] extends [4, 3] ? 24 :
[N, K] extends [4, 4] ? 24 :
[N, K] extends [5, 2] ? 20 :
[N, K] extends [5, 3] ? 60 :
[N, K] extends [5, 4] ? 120 :
[N, K] extends [5, 5] ? 120 :
number; // Fallback
type PermuteTest1 = Permute<4, 2>; // 12 (4 permute 2)
type PermuteTest2 = Permute<5, 3>; // 60 (5 permute 3)
๐ ๏ธ Type-Level Arithmetic Utilities
๐ง Number Validation and Constraints
// ๐ฏ Number type guards
type IsEven<N extends number> =
Modulo<N, 2> extends 0 ? true : false;
type IsOdd<N extends number> =
IsEven<N> extends true ? false : true;
// โ
Even/odd test cases
type EvenTest1 = IsEven<4>; // true
type EvenTest2 = IsEven<5>; // false
type OddTest1 = IsOdd<3>; // true
type OddTest2 = IsOdd<6>; // false
// ๐ฏ Range validation
type InRange<N extends number, Min extends number, Max extends number> =
SafeSubtract<N, Min> extends never ? false :
SafeSubtract<Max, N> extends never ? false : true;
type RangeTest1 = InRange<5, 1, 10>; // true
type RangeTest2 = InRange<15, 1, 10>; // false
type RangeTest3 = InRange<0, 1, 10>; // false
// ๐ Number clamping
type Clamp<N extends number, Min extends number, Max extends number> =
InRange<N, Min, Max> extends true ? N :
SafeSubtract<N, Min> extends never ? Min :
SafeSubtract<Max, N> extends never ? Max : N;
type ClampTest1 = Clamp<5, 1, 10>; // 5 (in range)
type ClampTest2 = Clamp<15, 1, 10>; // 10 (clamped to max)
type ClampTest3 = Clamp<-5, 1, 10>; // 1 (clamped to min)
// ๐ฏ Digit operations
type DigitCount<N extends number> =
`${N}` extends `${string}${string}${string}${string}${string}` ? 5 :
`${N}` extends `${string}${string}${string}${string}` ? 4 :
`${N}` extends `${string}${string}${string}` ? 3 :
`${N}` extends `${string}${string}` ? 2 : 1;
type DigitTest1 = DigitCount<42>; // 2
type DigitTest2 = DigitCount<123>; // 3
type DigitTest3 = DigitCount<5>; // 1
๐ Mathematical Sequences
// ๐ฏ Arithmetic sequence
type ArithmeticSequence<Start extends number, Diff extends number, Length extends number> =
Length extends 0 ? [] :
Length extends 1 ? [Start] :
Length extends 2 ? [Start, SafeAdd<Start, Diff>] :
Length extends 3 ? [Start, SafeAdd<Start, Diff>, SafeAdd<SafeAdd<Start, Diff>, Diff>] :
number[]; // Fallback for longer sequences
type ArithSeq = ArithmeticSequence<2, 3, 3>; // [2, 5, 8]
// ๐ Geometric sequence (powers of 2)
type PowersOfTwo<N extends number> =
N extends 0 ? [1] :
N extends 1 ? [1, 2] :
N extends 2 ? [1, 2, 4] :
N extends 3 ? [1, 2, 4, 8] :
N extends 4 ? [1, 2, 4, 8, 16] :
number[]; // Fallback
type Powers = PowersOfTwo<4>; // [1, 2, 4, 8, 16]
// ๐ข Sum of arithmetic sequence
type ArithmeticSum<First extends number, Last extends number, Count extends number> =
FastMultiply<SafeAdd<First, Last>, Count> extends infer Product ?
Product extends number ? FastDivide<Product, 2> : never : never;
type ArithSumTest = ArithmeticSum<1, 10, 10>; // 55 (sum of 1+2+...+10)
๐งช Advanced Applications and Demos
๐๏ธ Type-Safe Configuration Validation
// ๐ฏ Port number validation
type ValidPort<P extends number> =
InRange<P, 1, 65535>;
type PortTest1 = ValidPort<8080>; // true
type PortTest2 = ValidPort<70000>; // false
// ๐ Percentage validation
type ValidPercentage<P extends number> =
InRange<P, 0, 100>;
type PercentTest1 = ValidPercentage<50>; // true
type PercentTest2 = ValidPercentage<150>; // false
// ๐ฎ Game score validation
type ValidScore<S extends number> =
InRange<S, 0, 999999>;
// ๐
Date component validation
type ValidDay<D extends number> =
InRange<D, 1, 31>;
type ValidMonth<M extends number> =
InRange<M, 1, 12>;
type ValidYear<Y extends number> =
InRange<Y, 1900, 2100>;
// โ
Date validation tests
type DayTest = ValidDay<15>; // true
type MonthTest = ValidMonth<13>; // false
type YearTest = ValidYear<2024>; // true
๐ฏ Compile-Time Algorithm Verification
// ๐งฎ Algorithm correctness proofs
type QuadraticFormula<A extends number, B extends number, C extends number> = {
discriminant: SafeSubtract<FastMultiply<B, B>, FastMultiply<4, FastMultiply<A, C>>>;
hasRealSolutions: SafeSubtract<FastMultiply<B, B>, FastMultiply<4, FastMultiply<A, C>>> extends never ? false : true;
};
// Test: xยฒ - 5x + 6 = 0 (should have real solutions)
type QuadTest = QuadraticFormula<1, -5, 6>;
// ๐ฏ Mathematical invariants
type PythagoreanTheorem<A extends number, B extends number, C extends number> =
SafeAdd<FastMultiply<A, A>, FastMultiply<B, B>> extends FastMultiply<C, C> ? true : false;
type PythTest1 = PythagoreanTheorem<3, 4, 5>; // true (3ยฒ + 4ยฒ = 5ยฒ)
type PythTest2 = PythagoreanTheorem<5, 12, 13>; // true (5ยฒ + 12ยฒ = 13ยฒ)
// ๐ Series convergence checks
type GeometricSeriesSum<A extends number, R extends number, N extends number> =
R extends 1 ? FastMultiply<A, N> :
number; // Would need more complex calculation
// ๐ Statistical validation
type MeanOfTwo<A extends number, B extends number> =
FastDivide<SafeAdd<A, B>, 2>;
type VarianceOfTwo<A extends number, B extends number> =
MeanOfTwo<A, B> extends infer Mean ?
Mean extends number ?
FastDivide<
SafeAdd<
FastMultiply<SafeSubtract<A, Mean>, SafeSubtract<A, Mean>>,
FastMultiply<SafeSubtract<B, Mean>, SafeSubtract<B, Mean>>
>,
2> : never : never;
type MeanTest = MeanOfTwo<4, 6>; // 5
// type VarTest = VarianceOfTwo<4, 6>; // Complex calculation
๐ Performance and Optimization Proofs
// โก Big O notation as types
type TimeComplexity = 'O(1)' | 'O(log n)' | 'O(n)' | 'O(n log n)' | 'O(nยฒ)' | 'O(2^n)';
type AlgorithmComplexity<T extends string> = {
readonly algorithm: T;
readonly timeComplexity: TimeComplexity;
readonly spaceComplexity: TimeComplexity;
};
type BinarySearch = AlgorithmComplexity<'BinarySearch'> & {
readonly timeComplexity: 'O(log n)';
readonly spaceComplexity: 'O(1)';
};
type QuickSort = AlgorithmComplexity<'QuickSort'> & {
readonly timeComplexity: 'O(n log n)';
readonly spaceComplexity: 'O(log n)';
};
// ๐ฏ Memory usage calculations
type MemoryUsage<Elements extends number, BytesPerElement extends number> =
FastMultiply<Elements, BytesPerElement>;
type ArrayMemory = MemoryUsage<1000, 4>; // 4000 bytes for 1000 integers
// ๐ Cache efficiency metrics
type CacheLineSize = 64; // bytes
type CacheLines<Bytes extends number> =
FastDivide<Bytes, CacheLineSize>;
type CacheTest = CacheLines<256>; // 4 cache lines
๐ Key Takeaways
Youโve mastered the mathematical dimension of TypeScriptโs type system! Hereโs what you now command:
- โ Type-level arithmetic with addition, subtraction, multiplication, and division ๐ช
- โ Advanced mathematical operations including GCD, factorials, and prime checking ๐ก๏ธ
- โ Recursive algorithms and mathematical sequence generation ๐ฏ
- โ Real-world applications in finance, statistics, and algorithm verification ๐
- โ Performance analysis and complexity proofs at the type level ๐
- โ Mathematical invariants and theorem proving with types โจ
- โ Compile-time validation of mathematical constraints and properties ๐
Remember: Type-level arithmetic opens up infinite possibilities for compile-time computation and verification! ๐ค
๐ค Next Steps
Congratulations! ๐ Youโve reached the mathematical summit of TypeScriptโs type system!
Hereโs what to do next:
- ๐ป Apply type-level arithmetic to validate business logic at compile time
- ๐๏ธ Build mathematical libraries with type-level proofs and guarantees
- ๐ Explore the next tutorial in our series to continue your TypeScript mastery
- ๐ Create compile-time calculators and mathematical tools
- ๐ Investigate functional programming languages for more mathematical type features
- ๐ฏ Build APIs that encode mathematical constraints directly in the type system
- ๐ Push the boundaries of whatโs computable at the type level
Remember: You now possess the power to turn TypeScriptโs type system into a mathematical proving ground! Use this knowledge to build incredibly safe and verified systems. ๐
Happy type-level computing! ๐๐ขโจ