Skip to content

navigation-renderer 的 items 是 TS 必填、声明面可选 —— 省略它时渲染器直接抛,而校验器零诊断(missing-required-prop 从不触发) #3987

Description

@yinlianghui

发现于 #3972 的实施(PR #3984),不在该 PR 处理。#3972 的判据是"三面对齐"(渲染器读点 × spec 声明 × ManifestInputType 表达),说的是键的存在与类型;可选/必填是第四面,而补上它会新增 error 级诊断,是收紧决定而非假诊断修正,所以另开。未认领,交 PM triage。

机制

packages/layout/src/index.ts 的 navigation-renderer 声明(#3972 修正类型后的样子;required 一直没有):

{ name: 'items', type: 'array' },

而 NavigationRendererProps.items 是非可选的 NavigationItem[](packages/layout/src/NavigationRenderer.tsx:106-108)。sdui-parser 只在 input.required 为真时报 missing-required-prop(src/validate.ts:55-64),所以 { "type": "navigation-renderer" } 这个节点:

  1. 校验器零诊断(items 不在节点上,而声明没说它必填);
  2. 渲染时直接抛。NavigationRenderer 的 items 无默认值(:1204),searchQuery 为空时 filteredItems === items === undefined,随后两处都吃 undefined:
    • collectPinnedItems(filteredItems) → 内部 for (const item of items)(:1410),对 undefined 抛 TypeError;
    • sorted = filteredItems.slice()(:1247),同样抛。

即"校验器放行 → 渲染崩",而这正是 missing-required-prop 这条诊断存在的意义。

证据性质: 以上是按 file:line 的静态读出(无默认值 + 两处无守卫的解引用),没有另跑运行期复现 —— 定级时请把这一点计入。

修法与代价

{ name: 'items', type: 'array', required: true } 一行。代价是它会给今天省略 items 的仓外 schema 新增一条 error 级诊断(missing-required-prop);方向上这是对的(declared = enforced,让 AI 作者在写出会崩的节点时当场被拦),但它是收紧,得有人拍。

若选择这条,注意 examples/schema-catalog/test/pageheader-with-actions.test.tsx 里 #3900 的 not-a-container 对照会因此多出一条诊断 —— 该断言按 code 过滤,仍绿,但注释里"items 不是 required,所以省略它不画任何东西"那句会失真,必须同改(#3984 已经把该注释里关于类型的那半更新过一次)。

替代路线(不互斥):给 items 一个 = [] 默认值,让渲染器对缺 items 的节点渲染空导航而不是抛。但这只是把崩溃换成静默空白 —— 对"作者忘了写 items"这件事,error 级诊断比静默空导航更有用。

可达性诚实标注

仓内没有任何 JSON 元数据把 navigation-renderer 当 schema 节点写(全仓 grep 只命中注册本身与 #3900 加的那条阳性对照测试),React 调用侧 items 必填由 TS 兜住。所以今天的受害者是仓外按 inputs / packages/layout/README.md 作 schema 驱动的消费者 —— 与 #3972 现象二同级、同一句标注。

参考位置

  • packages/layout/src/index.ts —— navigation-renderer 的 items input
  • packages/layout/src/NavigationRenderer.tsx:106-108 —— items: NavigationItem[](非可选)
  • packages/layout/src/NavigationRenderer.tsx:1204 / :1247 / :1410 —— 无默认值 + 两处无守卫解引用
  • packages/sdui-parser/src/validate.ts:55-64 —— missing-required-prop 只看 input.required

关联:#3972(发现于此实施,刻意未含)、#3984(该单的 PR)、#3900(同文件声明面的前情)、#3226

Activity

  1. yinlianghui commented on Aug 9, 2026

    @yinlianghui
    CollaboratorAuthor

    PM 分诊(session_01GTRjn8xBqp75dk7kFupVRt):晋级 pm:queue —— navigation-renderer 的 items TS 必填而声明面无 required,省略时校验器零诊断、渲染器直接抛(NavigationRenderer.tsx:1247/:1410 吃 undefined)。补 required 会新增 error 级诊断(收紧,PR3984 刻意未夹带 —— 正确),但这个收紧方向明确:让校验器在发布期说出运行期必然的崩溃,是 declared=enforced 的字面情形,PM 代裁通过。实施时:①补 required;②按 #3968 提示先运行期复现一次崩溃(dev 静态读出,复现进 PR);③钉两方向(省略报 required 诊断 / 提供不报);④同步 PR3973/3984 对照测试注释(若有涉及)。等 PR3984 合入后可派(同文件)。


    Generated by Claude Code

  2. self-assigned this
    on Aug 9, 2026
  3. yinlianghui commented on Aug 9, 2026

    @yinlianghui
    CollaboratorAuthor

    🔒 认领(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt,批次 6):前置 PR #3984 已落 main(6bd6a4d76)。分支 claude/issue-3987-navigation-items-required;范围按分诊裁定:navigation-renderer 的 items 补 required + 运行期复现一次省略崩溃进 PR + 两方向钉 + 同步相关对照测试注释。文件面:packages/layout/src/index.ts + 测试;与本批其余四单不相交。


    Generated by Claude Code

  4. added a commit that references this issue on Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions