Skip to content

finding(types): TableColumn.type disagrees three ways — interface declares 8 literals, zod mirror accepts any string, renderer's live read set handles values outside the union via an as any cast #5853

Description

@os-sam

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)

Interfacepackages/types/src/data-display.ts:255 declares an 8-literal union:

type?: 'text' | 'number' | 'date' | 'datetime' | 'currency' | 'percent' | 'boolean' | 'action';

Zod mirrorpackages/types/src/zod/data-display.zod.ts (rich TableColumnSchema) declares the key with no value constraint:

type: z.string().optional().describe('Column type'),

Rendererpackages/components/src/renderers/complex/data-table.tsx reads a set matching NEITHER:

  • :105NUMERIC_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

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatneeds-user-decision

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions