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.tsnavigation-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. 渲染时直接抛。NavigationRendereritems 无默认值(: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#3900not-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-rendereritems 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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions