Measured while sweeping #6143 (component reference pages re-declaring their own interface). Filed unassigned, not fixed there — #6143's dispatch order rules this class out of its scope explicitly:
A documented key the renderer genuinely reads but the type does not declare is an undeclared-but-consumed capability — a types defect, not a docs defect, and it goes to a separate card rather than being edited away.
This is that card, with the measurement in it.
⚠️ Edited once on filing day to restore two fragments GitHub's body sanitizer ate — it strips anything shaped like an HTML tag, so angle-bracket generics and placeholders are written in words here. Nothing else changed.
What was measured
All 76content/docs/components/** pages, every interface declared in their ## Schema blocks (98 names), each documented key tested for membership against the builtpackages/*/dist/*.d.ts resolved through the gate's own derivePackageTypePaths() (@object-ui/types resolving to packages/types/dist/index.d.ts, 47 entry files from dist/, 0 from src/).
68 documented keys are not declared members of their shipped type. For each, the renderer was read to see whether it actually consumes the key — a schema. dotted read of that key name off the schema object, or the key destructured out of schema. 13 are genuinely read. Those are capabilities that work at runtime and that no type declares.
The 13
| page | type | key | read at |
|---|
basic/text.mdx | TextSchema | content | renderers/basic/text.tsx:51,56 — {schema.content || schema.value} |
complex/carousel.mdx | CarouselSchema | opts | renderers/complex/carousel.tsx:23 — opts={schema.opts} |
complex/carousel.mdx | CarouselSchema | orientation | carousel.tsx:24 — orientation={schema.orientation || 'horizontal'} |
complex/carousel.mdx | CarouselSchema | itemClassName | carousel.tsx:30 — className={schema.itemClassName} |
complex/filter-builder.mdx | FilterBuilderSchema | wrapperClass | renderers/complex/filter-builder.tsx:37 |
data-display/tree-view.mdx | TreeViewSchema | nodes | renderers/data-display/tree-view.tsx:105 |
data-display/tree-view.mdx | TreeViewSchema | onNodeClick | tree-view.tsx:98,99 — invoked, not just read |
data-display/tree-view.mdx | TreeViewSchema | title | tree-view.tsx:115,117 |
form/checkbox.mdx | CheckboxSchema | required | renderers/form/checkbox.tsx:45,49 — drives the * affordance |
form/file-upload.mdx | FileUploadSchema | buttonText | renderers/form/file-upload.tsx:123 |
form/file-upload.mdx | FileUploadSchema | wrapperClass | file-upload.tsx:78 |
overlay/hover-card.mdx | HoverCardSchema | align | renderers/overlay/hover-card.tsx:24 — align={schema.align} |
overlay/context-menu.mdx | ContextMenuSchema | trigger | renderers/overlay/context-menu.tsx:64 |
⚠️context-menu.mdx is one of #6132's five files, currently with the maintainer — that row is recorded, not actioned.
Why this is not visible today, and will not become visible
These reads type-check because BaseSchema ends with [key: string]: any (#5155, open, pm:queue, maintainer-ruled 2026-08-19). Every one of these schemas inherits it, so schema.trigger on a type that never declared trigger resolves to any rather than erroring. The declaration and the consumption are connected by nothing at either end:
- the type does not declare the key, so no editor completes it and no annotation checks it;
- the renderer reads it anyway and it works;
- the docs document it — correctly, as a description of behavior — which is how these were found.
So the documentation is the only place in the repo that records these 13 capabilities, and it is the one place with no mechanical guard. #6143's sweep found them precisely because it was checking the docs against the types and had to decide, per key, which side was wrong.
What is NOT being claimed
That the docs are wrong. They are right — these keys work. The defect is that the shipped types under-declare a working surface. Two of the 13 (CheckboxSchema.required, TreeViewSchema.onNodeClick) are behavioral rather than cosmetic: required drives a visible required-marker, onNodeClick is invoked as a callback.
The fix direction is to declare them, not to delete the prose — but which of the 13 are intended public API versus incidental reads is a judgement this card does not make. CarouselSchema.opts in particular is a pass-through of the underlying carousel library's option bag and may want a narrower shape than "declare what is read".
Adjacent, deliberately excluded
Refs: #5155 (why these compile) · #6143 (where measured) · #6151 (sibling finding, same sweep, different mechanism) · #4631 (same family: three declared surfaces that disagree) · #5903 / #5018 (same shape, per-component, closed).
Generated by Claude Code
Measured while sweeping #6143 (component reference pages re-declaring their own
interface). Filed unassigned, not fixed there — #6143's dispatch order rules this class out of its scope explicitly:This is that card, with the measurement in it.
What was measured
All 76
content/docs/components/**pages, everyinterfacedeclared in their## Schemablocks (98 names), each documented key tested for membership against the builtpackages/*/dist/*.d.tsresolved through the gate's ownderivePackageTypePaths()(@object-ui/typesresolving topackages/types/dist/index.d.ts, 47 entry files fromdist/, 0 fromsrc/).68 documented keys are not declared members of their shipped type. For each, the renderer was read to see whether it actually consumes the key — a
schema.dotted read of that key name off the schema object, or the key destructured out ofschema. 13 are genuinely read. Those are capabilities that work at runtime and that no type declares.The 13
basic/text.mdxTextSchemacontentrenderers/basic/text.tsx:51,56—{schema.content || schema.value}complex/carousel.mdxCarouselSchemaoptsrenderers/complex/carousel.tsx:23—opts={schema.opts}complex/carousel.mdxCarouselSchemaorientationcarousel.tsx:24—orientation={schema.orientation || 'horizontal'}complex/carousel.mdxCarouselSchemaitemClassNamecarousel.tsx:30—className={schema.itemClassName}complex/filter-builder.mdxFilterBuilderSchemawrapperClassrenderers/complex/filter-builder.tsx:37data-display/tree-view.mdxTreeViewSchemanodesrenderers/data-display/tree-view.tsx:105data-display/tree-view.mdxTreeViewSchemaonNodeClicktree-view.tsx:98,99— invoked, not just readdata-display/tree-view.mdxTreeViewSchematitletree-view.tsx:115,117form/checkbox.mdxCheckboxSchemarequiredrenderers/form/checkbox.tsx:45,49— drives the*affordanceform/file-upload.mdxFileUploadSchemabuttonTextrenderers/form/file-upload.tsx:123form/file-upload.mdxFileUploadSchemawrapperClassfile-upload.tsx:78overlay/hover-card.mdxHoverCardSchemaalignrenderers/overlay/hover-card.tsx:24—align={schema.align}overlay/context-menu.mdxContextMenuSchematriggerrenderers/overlay/context-menu.tsx:64context-menu.mdxis one of #6132's five files, currently with the maintainer — that row is recorded, not actioned.Why this is not visible today, and will not become visible
These reads type-check because
BaseSchemaends with[key: string]: any(#5155, open,pm:queue, maintainer-ruled 2026-08-19). Every one of these schemas inherits it, soschema.triggeron a type that never declaredtriggerresolves toanyrather than erroring. The declaration and the consumption are connected by nothing at either end:So the documentation is the only place in the repo that records these 13 capabilities, and it is the one place with no mechanical guard. #6143's sweep found them precisely because it was checking the docs against the types and had to decide, per key, which side was wrong.
What is NOT being claimed
That the docs are wrong. They are right — these keys work. The defect is that the shipped types under-declare a working surface. Two of the 13 (
CheckboxSchema.required,TreeViewSchema.onNodeClick) are behavioral rather than cosmetic:requireddrives a visible required-marker,onNodeClickis invoked as a callback.The fix direction is to declare them, not to delete the prose — but which of the 13 are intended public API versus incidental reads is a judgement this card does not make.
CarouselSchema.optsin particular is a pass-through of the underlying carousel library's option bag and may want a narrower shape than "declare what is read".Adjacent, deliberately excluded
StackSchema.gap/.childrenlooked identical to this class and are not — they are declared onFlexSchemaand erased by the Omit-of-FlexSchema-minus-typeheritage clause collapsing under the index signature. Filed separately as finding(types):StackSchema, declared as Omit-of-FlexSchema-minus-type, erases every named member — it ships declaring onlytype, because Omit collapses underBaseSchema's index signature #6151.NavigationMenuItem.itemsandFilterField.valuewere candidates and were rejected on inspection: the renderer readsschema.items/schema.valueoff the top-level schema, not off the nested item type the docs declare them on. Those two are docs-only keys, not consumed capabilities.Refs: #5155 (why these compile) · #6143 (where measured) · #6151 (sibling finding, same sweep, different mechanism) · #4631 (same family: three declared surfaces that disagree) · #5903 / #5018 (same shape, per-component, closed).
Generated by Claude Code