onUndeclaredKey()

I'm encountering a discrepancy between the ArkType playground and my local Express development environment. This type definition works fine on the playground:
const exampleType = type({
code: type("string.trim").to(type("string > 0").describe("Not empty")),
name: type("string.trim").to(type("string > 0").describe("Not empty")),
description: type("string | null").optional(),
}).onUndeclaredKey("reject");
const exampleType = type({
code: type("string.trim").to(type("string > 0").describe("Not empty")),
name: type("string.trim").to(type("string > 0").describe("Not empty")),
description: type("string | null").optional(),
}).onUndeclaredKey("reject");
However, when I use the exact same definition in my project, it throws a ParseError during initialization: ParseError: Intersection at code of string and never results in an unsatisfiable type at throwError (...) at throwParseError (...) ... (rest of stack trace) It seems the .to() chain (type("string.trim").to(type("string > 0")...)) is causing an "unsatisfiable type" error locally. My environment: Node.js: v22.11.0 ArkType: 2.1.18 Project type: Express.js (using TypeScript/tsx) Why might this definition parse correctly on the playground but result in this intersection error in my project? Is there a different way to chain these kinds of refinements (trim then check length > 0) that would avoid this?
1 Reply
TizzySaurus
TizzySaurus3d ago
Fwiw the whole point of .to() is that you don't need the nested type() call. If you have it to get the .describe() you can use tuple syntax (iirc something like ["string > 0", "@", {description: "Not empty"}]). And description: type("string | null").optional() can be made more efficient by doing "description?": "string | null" (again, removing an unnecessary nested type() call) In fact since you're reusing the trimmed non-empty string I'd probably just store that as it's own type.
const trimmedNonEmptyString = type(...).describe(...)

const exampleType = {
code: trimmedNonEmptyString,
name: trimmedNonEmptyString,
"description?": "string | null"
}).onUndeclaredKey("reject")
const trimmedNonEmptyString = type(...).describe(...)

const exampleType = {
code: trimmedNonEmptyString,
name: trimmedNonEmptyString,
"description?": "string | null"
}).onUndeclaredKey("reject")

Did you find this page helpful?