Found while implementing #5821 (adding editable to the rich TableColumnSchema mirror). That card asked for the remaining 13 mirrored keys to be checked for correspondence; 12 correspond, type does not — and the divergence is three-sided, so the fix direction needs a decision rather than a mechanical tighten. Filed unassigned; deliberately NOT absorbed into #5821, whose scope fence is the editable key-level strip.
Measured (at da8db03a6)
Interface — packages/types/src/data-display.ts:255 declares an 8-literal union:
type?: 'text' | 'number' | 'date' | 'datetime' | 'currency' | 'percent' | 'boolean' | 'action';
Zod mirror — packages/types/src/zod/data-display.zod.ts (rich TableColumnSchema) declares the key with no value constraint:
type: z.string().optional().describe('Column type'),
Renderer — packages/components/src/renderers/complex/data-table.tsx reads a set matching NEITHER:
:105 — NUMERIC_EDIT_TYPES = new Set(['number', 'currency', 'percent', 'int', 'integer', 'float', 'double']) — four of these (int, integer, float, double) are outside the interface union.
:2152 — the inline-editor read goes through a cast: const editType = (col as any).type as string | undefined; with a comment saying the value is "forwarded from ObjectGrid's column inference" — the cast exists because the interface union does not cover what actually arrives.
Why it matters
Both failure directions are live:
- Validator looser than declaration:
TableColumnSchema.parse({header:'A', accessorKey:'a', type:'money'}) passes green (any string does), so the CLI validate route blesses a value the interface refuses and no renderer branch reads — the misauthored column silently falls through to default text rendering. This is the lenient-validation face that lets AI-authored metadata errors through.
- Declaration narrower than live behaviour: a producer writing the inferred numeric types the renderer genuinely supports (
type: 'int') fails tsc against TableColumn, which is why the renderer reads the key through as any — declared ≠ enforced, worked around instead of reconciled.
Any fix must pick the canonical value set first (is the union the contract, or is ObjectGrid's inference the contract?), then align the other two ends to it — tightening the mirror to the current 8-literal union without deciding that would break type: 'int' columns that render fine today.
Related
Generated by Claude Code
Found while implementing #5821 (adding
editableto the richTableColumnSchemamirror). That card asked for the remaining 13 mirrored keys to be checked for correspondence; 12 correspond,typedoes not — and the divergence is three-sided, so the fix direction needs a decision rather than a mechanical tighten. Filed unassigned; deliberately NOT absorbed into #5821, whose scope fence is theeditablekey-level strip.Measured (at
da8db03a6)Interface —
packages/types/src/data-display.ts:255declares an 8-literal union:Zod mirror —
packages/types/src/zod/data-display.zod.ts(richTableColumnSchema) declares the key with no value constraint:Renderer —
packages/components/src/renderers/complex/data-table.tsxreads a set matching NEITHER::105—NUMERIC_EDIT_TYPES = new Set(['number', 'currency', 'percent', 'int', 'integer', 'float', 'double'])— four of these (int,integer,float,double) are outside the interface union.:2152— the inline-editor read goes through a cast:const editType = (col as any).type as string | undefined;with a comment saying the value is "forwarded from ObjectGrid's column inference" — the cast exists because the interface union does not cover what actually arrives.Why it matters
Both failure directions are live:
TableColumnSchema.parse({header:'A', accessorKey:'a', type:'money'})passes green (any string does), so the CLIvalidateroute blesses a value the interface refuses and no renderer branch reads — the misauthored column silently falls through to default text rendering. This is the lenient-validation face that lets AI-authored metadata errors through.type: 'int') fails tsc againstTableColumn, which is why the renderer reads the key throughas any— declared ≠ enforced, worked around instead of reconciled.Any fix must pick the canonical value set first (is the union the contract, or is ObjectGrid's inference the contract?), then align the other two ends to it — tightening the mirror to the current 8-literal union without deciding that would break
type: 'int'columns that render fine today.Related
TableColumnSchemazod mirror omitseditable— a keydata-tablereads at three sites is silently stripped by validation, so a column locked witheditable: falsere-opens after parse #5821 — key-level strip in the same mirror (theeditableomission; this card is the value-level sibling in the same object)BaseSchemaonly — the ~17 sibling zod mirrors have nothing equivalent, and the class already has two confirmed instances #5684 — open finding that the types(zod): widen the BaseSchema mirror to match its TypeScript declaration #5680 anti-drift guard coversBaseSchemaonly; note a key-set parity guard would NOT catch this instance (the key is present — its value schema is what diverges)Generated by Claude Code