Measured while answering objectui#6576's measurement 2 ("have the inline members drifted from what each component actually reads?"). Filed separately: #6576 is about ANCHORING the two orphan prop types, and neither drillDown nor onRowClick is a BaseSchema member, so anchoring does not declare them. Reported rather than fixed under #6576's fence.
The fact
ObjectDataTableProps.schema (packages/plugin-dashboard/src/ObjectDataTable.tsx:35) is a hand-rolled inline object type carrying [key: string]: any. Two members are READ off it in production and declared nowhere on it:
drillDown — ObjectDataTable.tsx:643, const drillDown = schema.drillDown as DrillDownConfig | undefined; and again at 644, 974, 985, 987 (drives recordDrillEnabled, the drawer title, its fields and its target). The as DrillDownConfig cast is itself the evidence: the member arrives as any through the index signature, so the cast is doing the work a declaration would.onRowClick — ObjectDataTable.tsx:968, onRowClick: (schema as any).onRowClick ?? (recordDrillEnabled ? handleRowClick : undefined). Written as an explicit (schema as any) cast even though the index signature already types it any.
Neither is a stray: both are load-bearing reads on the widget's drill-to-record path.
Where each one IS declared
Both keys exist in @object-ui/types — on OTHER types, so the vocabulary is real and this is a missing declaration rather than an invented key:
| key | declared on | file |
|---|
drillDown?: DrillDownConfig | ChartSchema | packages/types/src/data-display.ts:1210 |
drillDown?: DrillDownConfig | PivotTableSchema | packages/types/src/data-display.ts:1378 |
onRowClick?: (row: any) = then void | DataTableSchema | packages/types/src/data-display.ts:941 |
Note DataTableSchema — the type this widget's own output is forwarded INTO — declares onRowClick and does not declare drillDown.
Why it matters
The [key: string]: any is what absorbs both. Measured with tsc --strict on a faithful reproduction of the two prop types:
- on
ObjectDataTableProps.schema as it stands, a literal carrying nosuchkey: 1 is ACCEPTED, and visible: 42 is ACCEPTED; - on
ObjectGalleryProps.schema, which is the same hand-rolled shape without an index signature, the same probes are REJECTED.
The causal reading is measurable, not inferred: the widget with the index signature drifted by two members; the widget without one has zero drift (10 declared members, the same 10 read). A misspelled drillDwon on an authored object-data-table node compiles clean today and silently disables drill-to-record; a rename of DrillDownConfig's members does not redden this reader.
Not a duplicate
- objectui#6882 is about
renderCellEditor and schema-level cellClassName on DataTableSchema (the published presentational type, in packages/components). This is about ObjectDataTableProps.schema (the plugin-dashboard wrapper's inline prop type) and two different keys. - objectui#6373 fixed what
enrich() EMITS into TableColumn[]. This is about what the widget READS off its own schema prop. - objectui#6576 is about the missing
BaseSchema ancestry. Anchoring to BaseSchema would declare none of these two keys.
Reproduce
grep -n "drillDown\|onRowClick" packages/plugin-dashboard/src/ObjectDataTable.tsx
sed -n '35,47p' packages/plugin-dashboard/src/ObjectDataTable.tsx
git grep -nE '^\s+(drillDown|onRowClick)\??:' packages/types/src
Refs: #6576 (the card this was measured under), #6882, #6373, #5155.
Generated by Claude Code
Measured while answering objectui#6576's measurement 2 ("have the inline members drifted from what each component actually reads?"). Filed separately: #6576 is about ANCHORING the two orphan prop types, and neither
drillDownnoronRowClickis aBaseSchemamember, so anchoring does not declare them. Reported rather than fixed under #6576's fence.The fact
ObjectDataTableProps.schema(packages/plugin-dashboard/src/ObjectDataTable.tsx:35) is a hand-rolled inline object type carrying[key: string]: any. Two members are READ off it in production and declared nowhere on it:drillDown—ObjectDataTable.tsx:643,const drillDown = schema.drillDown as DrillDownConfig | undefined;and again at 644, 974, 985, 987 (drivesrecordDrillEnabled, the drawer title, itsfieldsand itstarget). Theas DrillDownConfigcast is itself the evidence: the member arrives asanythrough the index signature, so the cast is doing the work a declaration would.onRowClick—ObjectDataTable.tsx:968,onRowClick: (schema as any).onRowClick ?? (recordDrillEnabled ? handleRowClick : undefined). Written as an explicit(schema as any)cast even though the index signature already types itany.Neither is a stray: both are load-bearing reads on the widget's drill-to-record path.
Where each one IS declared
Both keys exist in
@object-ui/types— on OTHER types, so the vocabulary is real and this is a missing declaration rather than an invented key:drillDown?: DrillDownConfigChartSchemapackages/types/src/data-display.ts:1210drillDown?: DrillDownConfigPivotTableSchemapackages/types/src/data-display.ts:1378onRowClick?: (row: any) =thenvoidDataTableSchemapackages/types/src/data-display.ts:941Note
DataTableSchema— the type this widget's own output is forwarded INTO — declaresonRowClickand does not declaredrillDown.Why it matters
The
[key: string]: anyis what absorbs both. Measured withtsc --stricton a faithful reproduction of the two prop types:ObjectDataTableProps.schemaas it stands, a literal carryingnosuchkey: 1is ACCEPTED, andvisible: 42is ACCEPTED;ObjectGalleryProps.schema, which is the same hand-rolled shape without an index signature, the same probes are REJECTED.The causal reading is measurable, not inferred: the widget with the index signature drifted by two members; the widget without one has zero drift (10 declared members, the same 10 read). A misspelled
drillDwonon an authoredobject-data-tablenode compiles clean today and silently disables drill-to-record; a rename ofDrillDownConfig's members does not redden this reader.Not a duplicate
renderCellEditorand schema-levelcellClassNameonDataTableSchema(the published presentational type, inpackages/components). This is aboutObjectDataTableProps.schema(the plugin-dashboard wrapper's inline prop type) and two different keys.enrich()EMITS intoTableColumn[]. This is about what the widget READS off its own schema prop.BaseSchemaancestry. Anchoring toBaseSchemawould declare none of these two keys.Reproduce
Refs: #6576 (the card this was measured under), #6882, #6373, #5155.
Generated by Claude Code