You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(spec): the remaining six recursive schemas name both type parameters, and the authoring artifacts stop spelling out defaults (#4195) (#4227)
`z.ZodType` takes `<Output, Input>` and `Input` DEFAULTS TO `unknown`, so naming
only the first parameter leaves `z.input` of anything embedding that schema
degraded to `unknown` — the authoring side of the contract, unchecked.
#4221 fixed `NavigationItemSchema`, the worst instance. This finishes the sweep:
the same defect was on six more — FormFieldSchema, JoinNodeSchema,
FieldNodeSchema, QuerySchema, FilterConditionSchema, NormalizedFilterSchema —
plus StateNodeSchema and ValidationRuleSchema with a documented caveat. The
`z.ZodType<T>` single-parameter form is now absent from the codebase.
Measured with a type probe: `QueryInput['joins']` and `['fields']` were
`unknown[]`; `z.input` of the FormField, Query, StateNode and ValidationRule
schemas was `unknown`. New exported types: `FormFieldInput`, `JoinNodeInput`,
`NavigationContributionInput`. `FilterCondition`, `NormalizedFilter` and
`FieldNode` carry no `.default()` or `.transform()`, so their input is their
output and the second parameter is simply the first.
The downstream close-out, which is the user-visible cost of the defect: #4171
had to spell out `expanded: false` (x16) and `target: '_self'` (x10) across
setup.app.ts, studio.app.ts and setup-nav.contributions.ts, because those
artifacts are annotated with the PARSED type where a `.default()`ed key is
required — and retyping them to the input surface would have traded eight loud
errors for no checking at all. With the input types real they are annotated
`AppInput` / `NavigationContributionInput`, the defaults are defaults again, and
the literals are checked for the first time (net -33 lines across the four).
Verified live rather than nominal: a literal omitting `expanded`/`target`
compiles, and one writing `defaultOpen` — the non-spec key #4171 found in
account.app.ts — is a compile error whose suggestion list names `expanded`.
StateNodeSchema and ValidationRuleSchema reuse their hand-written type for both
parameters: exact on the input side, loose on the output side (`StateNodeConfig`
marks `type` optional though `.default('atomic')` makes it always present;
`BaseValidationRuleShape` carries a `[key: string]: unknown` index signature).
Both were already that loose — input went from `unknown` to a real type, output
is untouched. The caveat is written at each declaration.
No CI gate, deliberately. #4195 proposed failing on "output precise but input
`unknown`"; measured after the fix, exactly two schemas match and both are
CORRECT — TranslationItemSchema and InlineActionSchema are `z.preprocess(...)`,
where an `unknown` input is zod's semantics, not a missing annotation.
Separating those from a real omission needs heuristics on emitted type names,
and per the rule in check-exported-any.ts's own header — zero false positives,
so red keeps meaning broken — a gate that cannot be made reliable is worse than
none. #4221's app.nav-type-assertions.ts is the better pattern where it applies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0 commit comments