Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding(types): ObjectMapSchema.objectName is declared REQUIRED but ObjectMap treats it as optional — the documented static-data route cannot be annotated #7296

Closed

Description

@yinlianghui

Found while covering content/docs/plugins/plugin-map.mdx for #5174 batch 5 (PR #7294). Filed unassigned and not fixed there — that PR's surface is the UNGATED_DOCS ledger plus three doc pages, and this is a package type.

What

ObjectMapSchema declares objectName as required:

export interface ObjectMapSchema extends BaseSchema {
    type: 'object-map';
    objectName: string;      // required
    data?: ViewData;
    staticData?: any[];
    ...
}

The component does not need it. ObjectMap branches on staticData first, and every other read of objectName is guarded:

  • packages/plugin-map/src/ObjectMap.tsx:153 — if (schema.staticData) { ... items: schema.staticData }, returning before the object branch.
  • :160 — if (schema.objectName) for the object branch.
  • :741 — if (!objectName) return; in the schema-fetch effect.
  • :218, :279, :322 — memo keys all written schema.objectName ?? '', i.e. authored defensively for the absent case.

So the "Value Provider (Static)" route the docs teach — staticData plus a map field mapping, no objectName — is a supported, exercised path that the type rejects.

Measured

content/docs/plugins/plugin-map.mdx documents three static-data maps (basic "With Static Data", "Value Provider (Static)", and the venueMap example). PR #7294 annotates every other schema literal on that page with ObjectMapSchema and leaves these unannotated, because annotating them produces TS2741 for a missing property the component never reads. That is a deliberate hole in the page's gate coverage, and it closes when this is decided.

Two readings, not resolved here

  1. objectName should be optional. It matches the component, it matches the memo keys already written ?? '', and it makes the documented static-data example expressible. Risk: objectName becomes optional for the object-provider route too, where it IS required — trading a false rejection for a missed one, unless expressed as a discriminated union.
  2. A discriminated union. staticData present ⇒ objectName optional; otherwise required. Precise, and it is the shape that would let a metadata author be told which keys their chosen provider needs. More type machinery, and ObjectMapSchema is referenced from ObjectQLComponentSchema and packages/plugin-map/dist/ObjectMap.d.ts, so the blast radius wants checking.

Reading 2 is the one that makes AI-authored metadata hard to get wrong, which is the direction this repo generally takes; reading 1 is the one-line version. Someone who owns the authoring contract should pick.

Reachability

Nothing breaks at runtime — static-data maps render today. The cost is type-level: a TypeScript author annotating a static-data map is told to supply an objectName that is never read, and the natural workaround is to invent a fake one, which then reaches the memo keys as real content.

Structurally the mirror of #5903 (ObjectGantt reads 11 keys ObjectGanttSchema does not declare — reads without declaration; this is a declaration without reads). Related: #5157 (whether ObjectMapConfigSchema should be .strict()).

Activity

  1. os-zhuang commented on Sep 5, 2026

    @os-zhuang
    Contributor

    分诊 —— 已修复,关闭

    在 origin/main a472b07 上复核:这张卡描述的缺陷已经不存在了,而且修法比卡片给的两条读法都好。

    objectName 已经是可选的

    packages/types/src/objectql.ts:2256   export interface ObjectMapSchema extends BaseSchema {
    packages/types/src/objectql.ts:2257     type: 'object-map';
    packages/types/src/objectql.ts:2270     objectName?: string;
    packages/types/src/objectql.ts:2275     data?: ViewData;
    packages/types/src/objectql.ts:2277     staticData?: any[];
    

    :2263-2268 的 docblock 逐字记下了缘由,与卡片的诊断完全一致:

    Optional since objectui#6939: a map authored on inline rows never reads this key, and requiring it refused three catalog entries that draw correctly. The requirement the renderer really has — at least one of data, staticData, objectName present — lives on the mirror as a refinement (requireRecordSource in zod/objectql.zod.ts).

    它没有停在"读法 1"上 —— 真正的约束搬到了 refinement

    卡片对读法 1 提的风险是"object-provider 那条路 objectName 本来必填,改可选就把误拒换成了漏检"。#6939 正好堵了这个:

    packages/types/src/zod/objectql.zod.ts:607   function requireRecordSource(type: 'object-map' | 'object-gantt') {
    packages/types/src/zod/objectql.zod.ts:612       if (RECORD_SOURCE_KEYS.some((key) => schema[key] !== undefined)) return;
    packages/types/src/zod/objectql.zod.ts:616         params: { code: 'RECORD_SOURCE_REQUIRED' },
    packages/types/src/zod/objectql.zod.ts:617         message: `\`${type}\` has no record source: declare one of \`data\`, \`staticData\` or \`objectName\``,
    packages/types/src/zod/objectql.zod.ts:640     objectName: z.string().optional().describe('… one of the three must be present (objectui#6939)'),
    packages/types/src/zod/objectql.zod.ts:651   }).superRefine(requireRecordSource('object-map'));
    

    也就是说:读法 1 的一行成本,拿到了读法 2 想要的精度 —— 作者仍会被告知"你三个记录源一个都没给",但不会被要求编一个渲染器根本不读的 objectName(卡片担心的"编一个假的,然后它进了 memo key 当真内容"这条路被堵死了)。

    正控制:同一个 refinement 也挂在 object-gantt 上(:840),所以这不是只给 map 打的补丁。

    顺带记下:卡片的 ObjectMap.tsx 行号已漂移

    给未来的读者,当前值(卡片写的是 :153/:160/:741/:218/:279/:322):

    packages/plugin-map/src/ObjectMap.tsx:159   if (schema.staticData) {
    packages/plugin-map/src/ObjectMap.tsx:166   if (schema.objectName) {
    packages/plugin-map/src/ObjectMap.tsx:224   memo = `${schema.type ?? 'map'}::${schema.objectName ?? ''}::…`
    packages/plugin-map/src/ObjectMap.tsx:780   if (!objectName) return;
    

    卡片的读代码结论(staticData 先分支、其余读全部有守卫、memo key 早就写成 ?? '')逐条成立 —— 诊断是对的,只是修复已经先落地了。

    剩下的尾巴

    卡片提到 PR #7294 在 content/docs/plugins/plugin-map.mdx 上故意留了三个静态数据示例不加注解("With Static Data" / "Value Provider (Static)" / venueMap),因为当时加注解会报 TS2741。那个障碍现在没了,那三块可以补注解、把该页的门禁覆盖洞补上。这属于 #5174 的文档批次,不值得单开卡 —— 已在此记录,domain:devx 席做 plugin-map.mdx 时顺手收。

    关闭为 completed。⛔ 分诊席只做分类与关闭已解决卡,不写码、不派单。


    Generated by Claude Code

  2. added
    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
    on Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanefinding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions