diff --git a/ark/type/__tests__/integration/allConfig.ts b/ark/type/__tests__/integration/allConfig.ts index 2208e49f04..86f70be4d5 100644 --- a/ark/type/__tests__/integration/allConfig.ts +++ b/ark/type/__tests__/integration/allConfig.ts @@ -83,6 +83,9 @@ configure({ "number.epoch": { description: "configured" }, + "number.finite": { + description: "configured" + }, "number.safe": { description: "configured" }, diff --git a/ark/type/__tests__/keywords/number.test.ts b/ark/type/__tests__/keywords/number.test.ts index 6de9e3645f..b01cfb779f 100644 --- a/ark/type/__tests__/keywords/number.test.ts +++ b/ark/type/__tests__/keywords/number.test.ts @@ -54,6 +54,22 @@ contextualize(() => { attest(Safe(NaN).toString()).snap("must be a number (was NaN)") }) + it("finite", () => { + const Finite = type("number.finite") + attest(Finite(42)).snap(42) + attest(Finite(-3.14)).snap(-3.14) + attest(Finite(0)).snap(0) + attest(Finite.allows(Number.MAX_VALUE)).equals(true) + attest(Finite.allows(-Number.MAX_VALUE)).equals(true) + attest(Finite(Infinity).toString()).snap( + "must be a finite number (was Infinity)" + ) + attest(Finite(-Infinity).toString()).snap( + "must be a finite number (was -Infinity)" + ) + attest(Finite(NaN).toString()).snap("must be a number (was NaN)") + }) + it("doesn't allow NaN by default", () => { attest(type.number.allows(Number.NaN)).equals(false) attest(type.number(Number.NaN).toString()).snap( diff --git a/ark/type/keywords/number.ts b/ark/type/keywords/number.ts index ba7fe57104..fc3529117e 100644 --- a/ark/type/keywords/number.ts +++ b/ark/type/keywords/number.ts @@ -34,11 +34,27 @@ export const integer = rootSchema({ divisor: 1 }) +const finite = rootSchema({ + domain: { + domain: "number", + numberAllowsNaN: false + }, + min: { + rule: -Number.MAX_VALUE, + meta: "a finite number" + }, + max: { + rule: Number.MAX_VALUE, + meta: "a finite number" + } +}) + export const number: number.module = Scope.module( { root: intrinsic.number, integer, epoch, + finite, safe: rootSchema({ domain: { domain: "number", @@ -64,6 +80,7 @@ export declare namespace number { export type $ = { root: number epoch: number + finite: number integer: number safe: number NaN: number