Uh oh!
There was an error while loading. Please reload this page.
docs(fields): annotate the remaining 22 Field Schema blocks against the exported *FieldMetadata (#6138 PR 2) - #6162
Merged
Conversation
…he exported *FieldMetadata (#6138 PR 2) Batch 2 of 2. Every `content/docs/fields` page opened with a `## Field Schema` block that declared an interface of its own, which type-checks no matter what it says because nothing in it refers to anything the packages export. Each of the 22 blocks left after batch 1 is now a literal annotated with that field type's exported `*FieldMetadata`, judged by the sealed type's excess-property check, and each page links the shared `widget-props.mdx` page batch 1 added. Sealedness was measured, not inherited: all 26 annotated types (22 field metadata types plus SelectOptionMetadata, GridColumnDefinition, UploadedFileMetadata and LookupColumnDef) carry no index signature and produce TS2353 on a nonsense key, while the same control against the components lane's BaseSchema/ButtonSchema produces zero diagnostics. Every divergence was checked against its renderer before being removed. Two keys the widgets genuinely read but no exported type declares are filed rather than deleted (#6153); the location field's undeclared value shape is filed as #6154. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
yinlianghui-tw
marked this pull request as ready for review
August 24, 2026 22:00
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#6138 — batch 2 of 2, the remaining 22
content/docs/fieldspages. Batch 1 (#6146) has merged; it added the sharedwidget-props.mdxpage and converted the other four, so the card is complete with this one.✅
origin/mainmerged in at7eb632749(merge commit, no rebase, no force-push). The 22 links to/docs/fields/widget-propsthat were red while this branch predated #6146 are green now —check-doc-linksprintsLinks are valid across 15 scan rootsat exit 0, and the doc-gate suites areTest Files 3 passed (3). The diff itself is unchanged; the merge only broughtmainunder it.What was wrong
Each of these pages opened with a
## Field Schemablock that declared an interface of its own. A self-declared interface with no imports type-checks no matter what it says, because nothing in it refers to anything the packages export, socheck-doc-snippet-typesreported the page green while being structurally unable to see whether the documented shape matched the shipped one.Each block is now a literal annotated with that field type's exported
*FieldMetadata, judged by the sealed type's excess-property check.Sealedness, verified per type rather than inherited
⭐ This mechanism only works against a sealed type. On an open one — a type ending in
[key: string]: any— an annotated literal accepts any key, so converting would turn an uncompiled vacuous block into a compiled vacuous block and raise blocks-to-compile while catching nothing. That is the measured state of the components lane (#6143).All 26 types this batch annotates against are sealed: the 22 field metadata types plus
SelectOptionMetadata,GridColumnDefinition,UploadedFileMetadataandLookupColumnDef. Verified by the nonsense-key control on each type individually — a literal carryingthisKeyIsCompleteNonsenseproducesTS2353naming the key — and by reading index-signature info off each type through the compiler (none, on all 26).TextFieldMetadataandBaseFieldMetadatawere probed alongside as lane controls and are sealed too.⭐ The harness carries a negative control, and that is what makes the 26 verdicts measurements rather than a uniformly silent instrument. In the same run, against the components lane's types, it reports the opposite — so it demonstrably can report open.
TS2353naming the keyButtonSchema(negative control)stringBaseSchema(negative control)stringThe vacuity, demonstrated and closed on a page from this batch
Page:
content/docs/fields/select.mdx. Mutations grep-confirmed on disk before any gate result was read, each leg under atrap … EXIT INT TERMrestore, with the fix committed first.Leg A — the pre-fix self-declared block restored from
main(228909995), wrong key injected:A key no shipped type declares passes green. That is the vacuity.
Leg B — the post-fix annotated literal, same page, same key:
Leg C — the nested option literal alone, which is new in this batch: the option objects are judged against
SelectOptionMetadata, so a wrong key inside one reddens too.Restore leg, confirmed on disk:
tooltip0,badge: 'new'0,interface SelectFieldSchema0,SelectFieldMetadata3, andgit status --short/git diff HEAD --statboth empty.Every divergence checked against its renderer
A key the renderer reads but no type declares is filed, not deleted; a key nothing reads and no type declares goes.
dependsOnon select metadataSelectField.tsx:98—const dependsOn = (config as any)?.dependsOn ?? dependsOnProp;, and no exported metadata type declares it (BaseFieldMetadatadeclares the snake_casedepends_on)descriptionon a lookup's static optionsLookupField.tsx:526readsopt.description;LookupFieldMetadata.optionsis declaredSelectOptionMetadata[], which has nodescription{ latitude, longitude }LocationField.tsx:15/:35produce and consume it; no exported type declares the value shapeeditableon grid.editablereads inGridField.tsx; declared by neitherGridColumnDefinitionnor the widget's ownGridColumn_id/namevalueand labelled bylabel; those two keys are read off records, not optionsFour documentation errors the conversion forced out:
grid.mdxgave a columnwidthas a string (it is a number of pixels) and documented aneditablekey that does not exist;formula.mdxofferedcurrencyas areturn_typewhere the shipped union is'text' | 'number' | 'boolean' | 'date' | 'datetime';user.mdxdocumented the value as a user object where the field stores the user's id. No type, export or union member was minted for any of them.Out of scope here and untouched: #6140 remains open.
Verification at the merged head
Count identity, predicted in writing before measuring (
predicted-merged.txt, timestamped 21:54:18Z, written after the new baseline was taken and before the merged head was measured). The baseline moved because #6146 landed, so the pre-merge numbers are dead: onorigin/mainat7797e3b74the gate reads223 documents / 179 covered (74 with ts/tsx) / 44 ungated,Covered blocks: 361 — 250 to compile, 111 fragments— exactly the pre-merge baseline pluswidget-props.mdx's one document and two blocks. My delta on top is unchanged by the merge (which touched none of my 22 pages): 21 conversions one-block-for-one-block,lookup.mdxbecoming two blocks,file.mdxkeeping one block with two consts, no document entering or leaving, noFRAGMENT_MARKER.7797e3b74)7eb632749)Gate union at the merged head
7eb632749, clean working tree, under the shared verify lock, each exit code captured before any pipe:check-doc-fence-languagesis new onmain(#6144) and arrived with the merge; it is included because the diff is 22 fenced blocks.The resolution control line is what proves the annotations bind to the built
dist/*.d.ts; the dependency closure was rebuilt after the merge (turbo run build,__EXIT_build=0).Root vitest from the repo root: the three doc-gate suites are
Test Files 3 passed (3),Tests 157 passed (157)— the link failure that stood while this branch predated #6146 is gone. The gate that arrived with the merge passes too:check-doc-fence-languages.test.ts,Test Files 1 passed (1),Tests 20 passed (20).Render check (taken pre-merge, on the same 22 files the merge did not touch) from served HTML, all 22 pages
HTTP 200. Positive: each page renders its exported metadata type name and the link to Field Widget Props. Negative:interface AutoNumberFieldSchema…interface VectorFieldSchema— all 22 — return 0 occurrences, as do the six removed helper interfaces (interface FileMetadata,interface ColumnDefinition,interface LocationValue,interface LookupOption,interface SelectOption,interface User).Declared narrowing on lint, as a measurement: every
files:block ineslint.config.jsis scoped to**/*.{ts,tsx}and no type-aware linting is configured (noprojectService/project), so no untouched file's verdict can move. Running eslint over the diff's own files reports, from eslint's own config resolution,File ignored because no matching configuration was suppliedfor 23 of 23 files (22.mdx+ 1 changeset.md), 0 errors. CI runs the full farm regardless.Not done here
No
FRAGMENT_MARKER;UNGATED_DOCSand the ledger untouched; no type, export or union member minted; no gate weakened. Draft PR, not marked ready, auto-merge not enabled.Generated by Claude Code