Math
The math category performs arithmetic in the type system. Every operation accepts number or bigint,
supports negative and floating point values, and coerces between number and bigint when a result
cannot be represented in the input’s type.
The $fail option
Section titled “The $fail option”Every math type takes a last type parameter, $O extends $StrictOptions<$O, X.$Options> = {}, whose
$fail key defaults to never:
type Add<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Add.$Options> = {}>$O['$fail'] is returned when the operation cannot be computed — most commonly when an input is the
wide number or bigint type instead of a literal. Supply your own value to distinguish a failure
from a legitimate never result.
type R1 = Add<1, 2> // 3type R2 = Add<number, 2> // nevertype R3 = Add<number, 2, { $fail: 'fail' }> // 'fail'Internally the operands are converted into a NumericStruct — a sign, digit tuple and exponent, similar
to a floating point representation — operated on, then converted back. That machinery lives in
numeric-struct.ts and is not part of the public API.
Add and Increment
Section titled “Add and Increment”type Add<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Add.$Options> = {}>type Increment<N extends number | bigint> // Add<N, 1>type R1 = Add<1, 2> // 3type R2 = Add<1.2, -2> // -0.8type R3 = Add<1n, 2.3> // 3.3, coerced to numbertype R4 = Add<9007199254740992, 1> // 9007199254740993n, coerced to biginttype R5 = Increment<41> // 42Subtract and Decrement
Section titled “Subtract and Decrement”type Subtract<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Subtract.$Options> = {}>type Decrement<N extends number | bigint> // Subtract<N, 1>type R1 = Subtract<100, 2> // 98type R2 = Subtract<1.2, 2> // -0.8type R3 = Subtract<1n, 2.3> // -1.3, coerced to numbertype R4 = Decrement<1> // 0Multiply
Section titled “Multiply”type Multiply<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Multiply.$Options> = {}>type R1 = Multiply<100, 2> // 200type R2 = Multiply<1.2, 2> // 2.4type R3 = Multiply<1n, 2.3> // 2.3, coerced to numbertype R4 = Multiply<0.5, 4> // 2Divide
Section titled “Divide”type Divide<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Divide.$Options> = {}>A / B. A result that does not terminate is truncated toward zero to $O['precision'] fractional digits,
16 by default, which gives Divide<1, 3> the same literal as the runtime 1 / 3. When a truncated result
has more digits than a number literal holds, more fractional digits are dropped until it fits.
type R1 = Divide<1, 4> // 0.25type R2 = Divide<1, 0.5> // 2type R3 = Divide<1, 3> // 0.3333333333333333type R4 = Divide<2, 3, { precision: 2 }> // 0.66type R5 = Divide<7n, 2n> // 3n, the same as Quotientbigint has no fractional values, so when either input is a bigint, Divide is Quotient. A zero divisor
returns $O['$fail'], as in Quotient, and so does a precision that is not a non-negative integer literal.
Quotient and Remainder
Section titled “Quotient and Remainder”type Quotient<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Quotient.$Options> = {}>type Remainder<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Remainder.$Options> = {}>Integer division. Quotient truncates toward zero, as bigint division and Math.trunc(A / B) do, and
Remainder is the type-level A % B, taking the sign of A. Together they satisfy
Quotient<A, B> * B + Remainder<A, B> = A. Mixing number and bigint gives a bigint.
type R1 = Quotient<7, 2> // 3type R2 = Quotient<-7, 2> // -3type R3 = Remainder<7, 2> // 1type R4 = Remainder<-7, 2> // -1type R5 = Quotient<7n, 2n> // 3nBoth cover integers only. A fractional input or a zero divisor returns $O['$fail'], since neither has
an integer result to return. Divide gives a fractional result.
type R6 = Quotient<1, 0> // nevertype R7 = Quotient<7.5, 2> // nevertype R8 = Remainder<1, 0, { $fail: 'fail' }> // 'fail'Comparisons
Section titled “Comparisons”type GreaterThan<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, GreaterThan.$Options> = {}>type GreaterThanOrEqual<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, GreaterThanOrEqual.$Options> = {}>type LessThan<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, LessThan.$Options> = {}>type LessThanOrEqual<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, LessThanOrEqual.$Options> = {}>GreaterThan performs A > B, GreaterThanOrEqual A >= B, LessThan A < B and LessThanOrEqual
A <= B.
type R1 = GreaterThan<100, 2> // truetype R2 = GreaterThan<1.2, 2> // falsetype R3 = LessThan<1, 2> // truetype R4 = GreaterThanOrEqual<1, 1> // truetype R5 = LessThanOrEqual<2, 1> // falseAll four compare number literals only. They resolve to $O['$fail'] for bigint and for the wide
number type. The OrEqual pair returns that $fail value as is, rather than its negation, and is true
for two identical number literals even when the comparison alone cannot compute it.
Max and Min
Section titled “Max and Min”type Max<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Max.$Options> = {}>type Min<A extends number | bigint, B extends number | bigint, $O extends $StrictOptions<$O, Min.$Options> = {}>Max returns whichever of A or B is larger, and Min whichever is smaller. Both are built on
GreaterThan and share its limits.
type R1 = Max<-1, 2> // 2type R2 = Max<1.2, 2> // 2type R3 = Min<-1, 2> // -1type R4 = Min<1.2, 2> // 1.2type Abs<N extends number | bigint, $O extends $StrictOptions<$O, Abs.$Options> = {}>The absolute value of N. Returns $O['$fail'] for the wide number and bigint types.
type R1 = Abs<-5> // 5type R2 = Abs<5> // 5type R3 = Abs<-1n> // 1ntype R4 = Abs<number> // neverMathPlus.ToNegative
Section titled “MathPlus.ToNegative”type ToNegative<N extends number | bigint>ToNegative is exported only through the MathPlus namespace. It converts N to negative, and returns
N unchanged if it is already negative or zero.
import type { MathPlus } from 'type-plus'
type R1 = MathPlus.ToNegative<5> // -5type R2 = MathPlus.ToNegative<0> // 0type R3 = MathPlus.ToNegative<-5> // -5There is no MathPlus.ToPositive: that is Abs.
MathPlus also holds every other math type on this page: Abs, Add, Decrement, Divide, GreaterThan,
GreaterThanOrEqual, Increment, LessThan, LessThanOrEqual, Max, Min, Multiply, Quotient, Remainder and Subtract. Each is the same type as the top-level one, so
MathPlus.Add<1, 2> and Add<1, 2> are the same type.