Skip to content

fix(zod): parenthesize optional and multi-value literal types in schema text - #445

Open
Mohammed Alkindi (MohammedAlkindi) wants to merge 1 commit into
microsoft:mainfrom
MohammedAlkindi:fix/zod-schema-text-parens
Open

Mohammed Alkindi (MohammedAlkindi) wants to merge 1 commit into
microsoft:mainfrom
MohammedAlkindi:fix/zod-schema-text-parens

Conversation

@MohammedAlkindi

Copy link
Copy Markdown

getZodSchemaAsTypeScript emits optional types as T | undefined and multi-value literals as a union of their values, but gave both object precedence, so they lost their parentheses. On main:

z.array(z.literal(["a", "b"]))                     "a" | "b"[]
z.array(z.string().optional())                     string | undefined[]
z.intersection(z.string().optional(), z.literal(["a", "b"]))  string | undefined & "a" | "b"
z.tuple([z.string()]).rest(z.number().optional())  [string, ...number | undefined[]]
z.tuple([z.string(), z.literal(["a", "b"]).optional()])  [string, "a" | "b"?]

The last two are not valid TypeScript, and the others describe a different type than the schema. getTypePrecedence now gives both union precedence. Single-value literals are unchanged.

npm test in typescript/: 121 pass. Six of the eight new tests fail on main; the other two check that single literals and union members stay unparenthesized.

…ma text

z.array(z.literal(['a', 'b'])) was emitted as "a" | "b"[], which TypeScript reads as "a" | ("b"[]). Optional types and multi-value literals are emitted as unions, so they now get union precedence and are parenthesized in array, intersection and tuple positions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant