Skip to content

app-schema-renderer 的 mobileNavMode 声明成自由文本 string,实现却是三值联合 —— 写错的值静默回落,且词表里的 'hamburger' 在渲染器零读点 #3985

Description

@yinlianghui

发现于 #3972 的实施(PR #3984),不在该 PR 处理 —— #3972 的完成范围是"对正确写法报假诊断"那一类(page-headericon/actionsnavigation-renderer.items 类型写错),这一条相反:声明面比实现更宽,于是该报的一条 invalid-enum 从来没报过。而且它的修法需要先定词表,不该由实施 agent 猜。未认领,交 PM triage。

#3818 同一失效家族(声明的语义与渲染器实际读点不符),但方向相反:#3818 是发布了 auto|custom 而渲染器只认已退役的旧词表;这里是根本没发布词表,而实现只兑现三值中的一个。

机制

packages/layout/src/index.tsapp-schema-renderer 声明:

{ name: 'mobileNavMode', type: 'string' },

而实现是三值联合(packages/layout/src/AppSchemaRenderer.tsx:57):

export type MobileNavMode = 'drawer' | 'bottom_nav' | 'hamburger';

ManifestInputType'enum',ManifestInputenum 数组字段(packages/sdui-parser/src/types.ts:51-73),checkType'enum' 会给出 error 级的 invalid-enum(validate.ts:130-140)—— 所以这个词表是完全表达得了的,和 #3832 的联合类型表达力问题无关。

后果是两条,都无诊断:

  1. 写错值静默回落。 作者(尤其 AI 作者)写 mobileNavMode: "bottom-nav"(连字符,而实现要的是下划线 bottom_nav)拿不到任何诊断:type: 'string' 判的只是 typeof value === 'string',于是通过;渲染器 :538showBottomNav = mobileNavMode === 'bottom_nav' 不成立,静默走 drawer。设计器那边同样把它渲染成自由文本输入框,而不是三选一。
  2. 词表里的 'hamburger' 本身零读点。 全文件对 mobileNavMode 的读只有 :430 的默认值(= 'drawer')与 :538=== 'bottom_nav',所以 'hamburger''drawer' 行为完全一致 —— 而 :411 的 JSDoc 把它写成 "hamburger(collapsed sidebar)",是个已发布却未实装的语义(page:header.iconpage:card.actions:spec 声明、渲染器零读点 —— 二择一(接线 / 按 showSubscriptionToggle 先例声明并写明 KNOWN GAP) #3829 / record:detailslayout 发布了 auto|custom 语义,渲染器唯一的读点只认 spec 已退役的 inline|compact —— auto/custom 从未被实装 #3818 的同一类)。

为什么不在 #3972 的 PR 里顺手改

"声明成 enum"这个动作要求先回答"三个值里哪些是真的",而两条路的公开契约不同:

另外任一条路都会新增 error 级诊断:今天写了词表外值的仓外消费者会从"静默回落"变成"校验报错"。方向上这是对的(declared = enforced,让 AI 作者当场被拦),但它是收紧决定,得有人拍。

可达性诚实标注

仓内没有任何 JSON 元数据把 app-schema-renderer 当 schema 节点写(全仓 grep 只命中注册本身);React 调用侧受 TS 约束,mobileNavMode 传错值编译期就红。所以今天的实际受害者只有仓外按 inputs / packages/layout/README.md 作 schema 驱动的消费者,以及"以为 'hamburger' 有效"的任何调用方(仓内是 0 个:唯一传值处是 __tests__/AppSchemaRenderer.test.tsx:513 传的 'bottom_nav')。因此按 observation-class 打 finding、不挂 pm:queue,定级请分诊时自行判断。

参考位置

  • packages/layout/src/index.ts —— app-schema-renderermobileNavMode input
  • packages/layout/src/AppSchemaRenderer.tsx:57 —— MobileNavMode 三值联合
  • packages/layout/src/AppSchemaRenderer.tsx:430 / :538 —— 全部两个读点
  • packages/layout/src/AppSchemaRenderer.tsx:411 —— 把 hamburger 写成 collapsed sidebar 的 JSDoc
  • packages/sdui-parser/src/validate.ts:130-140 —— invalid-enum(error 级)

关联:#3972(发现于此实施)、#3984(该单的 PR)、#3818(同族、方向相反)、#3829(声明了却零读点)、#3832(不同根因:ComponentInput.type 表达力)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions