Type-Level Comparisons
Compare numbers entirely at the type level.
Type-Level Comparisons is a free TypeScript Academy lesson on CoddyKit. This is 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, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 4 lessons in total.
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.
Learn TypeScript with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 101
- Lessons
- 352
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. 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. The TypeScript Academy course includes 4 lessons in total.
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, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
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.
All lessons in this course
- Counting with Tuple Length
- Type-Level Addition and Subtraction
- Type-Level Comparisons
- Practical Numeric Type Utilities