Type-Level Comparisons
Compare numbers entirely at the type level.
Type-Level Comparisons is a free TypeScript Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Comparing Numbers
To compare numeric literal types you again lean on tuples. The idea: shrink both numbers in lockstep and see which hits zero first. Whichever reaches the empty tuple first is the smaller number.
type BuildTuple<N extends number, Acc extends unknown[] = []> =
Acc["length"] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>;Equality of Literals
Numeric literal equality uses mutual assignability. Two literals are equal when each extends the other. Wrapping in tuples avoids union surprises.
type NumEquals<A extends number, B extends number> =
[A] extends [B] ? ([B] extends [A] ? true : false) : false;
type X = NumEquals<3, 3>; // true
type Y = NumEquals<3, 4>; // falseGreater Than by Shrinking
For A > B, build tuples for both and remove one element from each per step. If B empties first while A still has elements, then A is larger.
type GreaterThan<A extends number, B extends number> =
BuildTuple<A> extends [...BuildTuple<B>, unknown, ...unknown[]]
? true : false;
type X = GreaterThan<5, 3>; // true
type Y = GreaterThan<3, 5>; // falseHow the Pattern Reads
The pattern [...BuildTuple<B>, unknown, ...unknown[]] means: a prefix of length B, then at least one more element. If A fits that, A has more elements than B, so A > B.
type A = GreaterThan<4, 4>; // false (no extra element)
type B = GreaterThan<6, 2>; // trueLess Than
LessThan is just GreaterThan with the arguments flipped. Reuse rather than re-derive.
type LessThan<A extends number, B extends number> =
GreaterThan<B, A>;
type X = LessThan<3, 5>; // true
type Y = LessThan<5, 3>; // falseGreater or Equal
Combine comparison with equality. A >= B is true when A > B or A == B.
type Gte<A extends number, B extends number> =
GreaterThan<A, B> extends true
? true
: NumEquals<A, B>;
type X = Gte<5, 5>; // true
type Y = Gte<3, 5>; // falseRecursive Comparison
An alternative compares by decrementing both until one reaches zero. This shows the lockstep idea explicitly: whoever hits zero first is smaller.
type Cmp<A extends number, B extends number> =
A extends 0
? (B extends 0 ? "eq" : "lt")
: B extends 0
? "gt"
: Cmp<Dec<A>, Dec<B>>;
type X = Cmp<3, 5>; // "lt"The Dec Dependency
The recursive version needs Dec from the previous lesson. Each step removes one mark from each side. When both are zero they are equal; if only one is zero, the other is greater.
type Dec<N extends number> =
BuildTuple<N> extends [unknown, ...infer R] ? R["length"] : 0;Equality vs Assignability
Be careful: number extends number is true, but that is not literal equality. Comparisons here assume specific literal types like 3 and 5, not the wide number type.
type A = NumEquals<3, 3>; // true
type B = 3 extends number ? 1 : 0; // 1 (assignability, not equality)Building a Sort Key
With comparison you can encode ordering rules. For example, decide at the type level whether a tuple of two numbers is sorted ascending.
type IsSorted<A extends number, B extends number> =
GreaterThan<A, B> extends true ? false : true;
type X = IsSorted<2, 5>; // true
type Y = IsSorted<5, 2>; // falseUse Sparingly
Comparisons cost recursion. They are great for guarding small bounded values (indices, fixed limits) but are not a general numeric library. Keep operands small and prefer the prefix-pattern form, which is shallower than full lockstep recursion.
type A = GreaterThan<9, 4>; // true (cheap, prefix pattern)Quick Check
Test your understanding of type-level comparisons.
Recap
You can now order numbers in the type system.
- Equality via mutual assignability of literals.
GreaterThanvia a B-length prefix plus an extra element.LessThanflips the arguments;Gteadds equality.- Works on small literal numbers, not the wide
numbertype.
Next: turning all this into practical utilities.
Frequently asked questions
Is the “Type-Level Comparisons” lesson free?
Yes — the full text of “Type-Level Comparisons” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Type-Level Comparisons”?
Compare numbers entirely at the type level. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Type-Level Comparisons” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.