Report a bug
🔎 Search Terms
regex, \d+, ${number}, Infinity, long digit string, arkregex, never incorrect
🧩 Context
- ArkType version: 2.2.5 (arkregex 0.0.10)
- TypeScript version (5.1+): 5.1.6, 5.3.3, 5.4.5, 5.9.3, 7.0.2, 7.1.0-dev.20260926.1 (same result on each;
${number} rejecting non-finite strings is standard TypeScript behavior, so this isn't version-specific)
- Other context you think may be relevant (JS flavor, OS, etc.): Node 24, macOS
🧑💻 Repro
Playground Link: N/A. The playground doesn't resolve regex types yet (regex() is any there, see #1529, and type("/^\\d+$/") reports "not allowed here"), so the repro below was verified with a local install of arktype@2.2.5 instead.
import { type } from "arktype"
const Digits = type("/^\\d+$/")
type Digits = typeof Digits.infer // `${number}`
// "1" followed by 309 zeros
const big =
"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
Digits(big) // passes validation and returns the string
const x: Digits = big
// ❌ Type '"1000…0"' is not assignable to type '`${number}`'
A string is only a ${number} if Number(s) is finite, and Number(big) is Infinity. So any digit run above ~1.8e308 passes validation but isn't assignable to the inferred type. The same happens with regex("^\\d+$"), with \d*, and with digit runs inside larger patterns such as ^v\d+\.\d+$ and the semver core regex.
It's an edge case, but it breaks the guarantee from the ArkRegex announcement that inferred types are "at worst imprecise and never incorrect": validated data ends up typed as something it isn't.
A sound replacement for \d+ that works on every supported TS version (5.1+):
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
type DigitsPlus = Lowercase<string> &
Uppercase<string> &
`${Digit}${string}` &
`${string}${Digit}`
It has no length limit and still rejects things like "1e5", "0x1f" and " 1". I'm also opening a feature request with a more precise version for TS 5.3+.
Report a bug
🔎 Search Terms
regex, \d+, ${number}, Infinity, long digit string, arkregex, never incorrect
🧩 Context
${number}rejecting non-finite strings is standard TypeScript behavior, so this isn't version-specific)🧑💻 Repro
Playground Link: N/A. The playground doesn't resolve regex types yet (
regex()isanythere, see #1529, andtype("/^\\d+$/")reports "not allowed here"), so the repro below was verified with a local install ofarktype@2.2.5instead.A string is only a
${number}ifNumber(s)is finite, andNumber(big)isInfinity. So any digit run above ~1.8e308 passes validation but isn't assignable to the inferred type. The same happens withregex("^\\d+$"), with\d*, and with digit runs inside larger patterns such as^v\d+\.\d+$and the semver core regex.It's an edge case, but it breaks the guarantee from the ArkRegex announcement that inferred types are "at worst imprecise and never incorrect": validated data ends up typed as something it isn't.
A sound replacement for
\d+that works on every supported TS version (5.1+):It has no length limit and still rejects things like
"1e5","0x1f"and" 1". I'm also opening a feature request with a more precise version for TS 5.3+.