How to create schema for open-ended union using zod 4.0 #4934
-
|
Hi, I am wondering how to use zod schema to model this type : |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
|
Hi @chenxin-yan! I'm Dosu and I’m helping the zod team. You can define a Zod 4 schema that accepts import { z } from "zod";
const schema = z.union([z.literal("a"), z.literal("b"), z.string()]);However, due to how TypeScript infers types, the resulting type will be just If you want autocomplete for Let me know if this answers your question—feel free to close the issue if so! To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
-
|
This seems to work: import { z } from "zod/v4";
const schema = z.union([
z.literal("a"),
z.literal("b"),
z.string().transform((x) => x as string & {}),
]);
type Schema = z.infer<typeof schema>;
// type Schema = "a" | "b" | (string & {})You can extract that transformed string into a helper method if you use it often: const nonLiteralString = () => z.string().transform((x) => x as string & {});
const schema = z.union([
z.literal("a"),
z.literal("b"),
nonLiteralString(),
]); |
Beta Was this translation helpful? Give feedback.
Also a valid solution, probably marginally more performant.
Unless you want to use
z.toJSONSchema, then none of our solutions work -- mine gets rejected because it usestransform, yours results in a simple{ "type": "string" }json schema.If you or anyone else wants to do this and not lose the ability to convert to json schema, this seems to work:
Resulting schema is
{ "anyOf": [{ "type": "string", "const": "a" }, { "type": "string", "const": "b" }, { "type": "string" }] }.