Repository navigation
Conversation
`number` now rejects `Infinity` and `-Infinity` the same way it already rejects `NaN`, and reports them as the actual value (e.g. "must be a number (was Infinity)"). This changes default behavior: values that were accepted before, including by ranges like `number > 0`, are now rejected. The global `numberAllowsInfinity` config, or `numberAllowsInfinity: true` on a number domain schema, opts back in, mirroring `numberAllowsNaN`. `number.Infinity` and `number.NegativeInfinity` still match exactly those values and can be unioned with `number`. Discriminating a union on `typeof` no longer prunes a number domain that excludes NaN or Infinity, so `number | null` rejects them as well when compiled.
3 tasks done
Contributor
There was a problem hiding this comment.
ℹ️ No correctness issues found — one generated file needs regenerating.
Reviewed changes
- Domain
numberAllowsInfinity—ark/schema/roots/domain.tsadds the option, excludes±Infinityfromnumberby default in both traversal and compiled conditions, and reportsInfinity/-Infinityinactual. - Intersection semantics — intersecting two number domains now only allows
NaN/Infinityif both sides do, and falls back to a freshnumberdomain when neither side is a subset. The subset tests are correct. - Discriminant pruning —
pruneDiscriminantnow keeps anumberdomain that excludesNaN/Infinity, sotypeof-discriminated unions likenumber | nulland{ a: number } | { a: string }reject both in JIT and jitless mode (also fixes #1700). Verified runtime behavior is unchanged for the reworkedmatchsnapshot. - Config plumbing —
numberAllowsInfinityadded toArkSchemaConfig,defaultConfig, andGlobalOnlyConfigOptionName(global-only, matchingnumberAllowsNaN). - fast-check —
numberarbitraries passnoDefaultInfinity: !numberAllowsInfinity;noDefaultInfinityis present in the pinnedfast-check@3.23.2. - Docs/tests — primitives/configuration docs and
llms.txtupdated; new tests cover rejection, opt-out, intersections, and jitless. I ran the touched suites (number,config,match,discrimination, schema,testSimpleConfig) — all pass.
ℹ️ Stale generated @ark/schema DTS bundle
ark/docs/components/dts/schema.ts is a committed autogenerated bundle (from ark/repo/dtsGen.ts) whose inlined ArkSchemaConfig and GlobalOnlyConfigOptionName still list numberAllowsNaN but not numberAllowsInfinity. It feeds the playground's TypeScript server, and the docs deploy workflow runs only pnpm buildDocs (next build), which does not regenerate it — so the published types will lag until it is rebuilt. A prior change to config.ts (fe481db3) regenerated this file in the same PR.
Technical details
# Regenerate `ark/docs/components/dts/schema.ts`
## Affected sites
- `ark/docs/components/dts/schema.ts` — autogenerated bundle still declares `numberAllowsNaN?: boolean` and the `GlobalOnlyConfigOptionName` union without `numberAllowsInfinity`.
## Required outcome
- The committed bundle reflects the new `numberAllowsInfinity` field and `GlobalOnlyConfigOptionName` member.
## Suggested approach
- Run `pnpm build` (the `@ark/schema` build invokes `dtsGen()`) and commit the regenerated `ark/docs/components/dts/schema.ts`.deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Closes #1598
This implements the design @ssalbdivad described when closing #1605 (comment):
Behavior change
numbernow rejectsInfinityand-Infinityby default. This changes default behavior: values that validated before are now errors, including through ranges, sincenumber > 0used to acceptInfinity.Opting out
numberAllowsInfinitymirrorsnumberAllowsNaN:"arktype/config"before importingarktype:configure({ numberAllowsInfinity: true }). LikenumberAllowsNaN, it's a global-only option (added toGlobalOnlyConfigOptionName), so scopes and types can't set it.rootSchema({ domain: "number", numberAllowsInfinity: true }). LikenumberAllowsNaN, it throws for other domains."number | number.Infinity","number | number.NegativeInfinity".Details
Infinityor-Infinity, the wayNaNis. As withNaN, this also applies to other domains' errors, e.g.type("string")(Infinity)now ends with(was Infinity)instead of(was a number).numberAllowsInfinityprints asnumber | Infinity | -Infinity. With both options it printsnumber | NaN | Infinity | -Infinity.numberdomains only allowsNaNorInfinityif both sides do.number.Infinityandnumber.NegativeInfinityare unchanged.number | number.Infinitynow stays a union (number | Infinity).number & number.Infinityis now unsatisfiable, just likenumber & number.NaN.number.safeandnumber.epochalready rejected±Infinitythrough their bounds, but now reportmust be a number (was Infinity), matching NaN.number.integerdoes the same.typeofused to drop thenumberdomain check entirely (case "number": return true). That's whynumber | nullacceptedNaNin compiled mode while jitless rejected it.pruneDiscriminantnow keeps anumberdomain that excludes NaN or Infinity, so both are rejected innumber | null,{ a: number } | { a: string }, and so on. This also fixes Unions discriminated by typeof accept NaN for number (e.g.number | null) #1700, which has its own smaller PR, fix(schema): keep the NaN check when a union discriminates on typeof #1702, touching the same lines. Whichever merges second needs a small rebase: keep this PR'spruneDiscriminantcondition, and keep both sets of new tests innumber.test.ts.{ "type": "number" }). JSON can't representInfinity, andnumberAllowsNaNhas no JSON Schema handling either.@ark/fast-checknow passesnoDefaultInfinity: !numberAllowsInfinity, next to the existingnoNaN, sonumberarbitraries don't generate valuesnumberwould reject.numbersection of Primitives, and regeneratedllms.txt.Tests
keywords/number.test.ts:±Infinityis rejected bynumber,number > 0,number < 0andnumber.integer, and by the discriminated unionsnumber | nulland{ a: number } | { a: string }, with JIT and withjitless: true.numberAllowsInfinityworks on schemas, alone and combined withnumberAllowsNaN, including expressions and intersections.numberAllowsInfinityon a non-number domain throws.number | number.Infinityandnumber | number.Infinity | number.NegativeInfinity | nullaccept exactly those values.config.test.ts: globalnumberAllowsInfinity, mirroring thenumberAllowsNaNtest.integration/simpleConfig.tsandtestSimpleConfig.ts:numberAllowsInfinity: trueis applied to built-in keywords.number.safeInfinity messages, and the discriminant snapshots indiscrimination.test.tsandmatch.test.ts, whose"number"case now keeps its domain check.Checklist:
mainbranch (based on c34bf69)pnpm prCheckslocallySuggested changelog entry
Recent contributor PRs leave
CHANGELOG.mdto the release PRs, so this one doesn't edit it. Here's a suggested entry: