Skip to content

finding(fields): the location field's stored value shape ({ latitude, longitude }) is declared by no exported type, while LocationField both produces and consumes it #6154

Description

@yinlianghui-tw

Measured while converting content/docs/fields/location.mdx for #6138 (PR 2). Filed unassigned. Observation-class: nothing is broken at runtime — the gap is that a shape every consumer has to agree on is written down nowhere a consumer can import.

The shape

packages/fields/src/widgets/LocationField.tsx both writes and reads a two-key object:

:15 ? `${value.latitude || 0}, ${value.longitude || 0}`
:35 onChange({ latitude: lat, longitude: lng });

LocationFieldMetadata (@object-ui/types) declares exactly one key of its own, default_zoom?: number — correctly, because the coordinates are the value, not metadata. But no exported type declares the value either: a grep for latitude across packages/types/dist/*.d.ts finds only the map-block's latitudeFieldfield-name keys (designer.d.ts:434, objectql.d.ts:1600), which name a column, not this shape. packages/fields/dist/index.d.ts has one occurrence, inside a doc comment.

So the widget's value type is effectively unknown at the boundary (FieldWidgetComponentProps<T>), and the agreement lives in prose.

Adjacent evidence that the agreement is already loose: the same package's doc comment says the value parser "accepts { lat, lng } / { latitude, longitude }, a "lat,lng" string" — three spellings, none declared.

Why it surfaced now

location.mdx documented the shape as a self-declared interface LocationValue { latitude; longitude } inside its "Field Schema" block. #6138 replaces those self-declared interfaces with literals annotated against the exported types, so a shape with no exported type cannot be carried that way. The converted page describes the value in prose and points here rather than deleting the information — the coordinates are real, and a reader authoring a location field needs them.

Candidate resolutions — not decided here

  1. Export a value type (e.g. a LocationValue in @object-ui/types) and have LocationField take FieldWidgetComponentProps<LocationValue>. Then the docs page can annotate against it like every other page in the section, and the three accepted input spellings become a declared, checked normalisation.
  2. Leave it structural and treat the value as host-defined, in which case the doc page correctly stops at prose and this card closes as not-planned.

Option 1 is a new export, which is exactly the kind of thing that should be decided rather than minted by a docs change — which is why this is a card and not a commit.

Refs: #6138 (the conversion that measured it) · #6140 and #6153 (undeclared-but-consumed keys found in the same sweep — a different defect: those are keys the type should already cover).


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