fix(types): open the BulkActionParam.options entry the renderer already forwards (#3309) - #3772
Merged
Merged
Conversation
…dy forwards (#3309) `BulkActionParam.options` 的 entry 之前是封闭的 `{ label, value }`,而这条路径上 其余三层都不同意它: - 运行期 `bulkParamToField` 把每个 entry 整体 spread 进交给 widget 的 field metadata(`{ ...o, value: String(o.value) }`),额外键全部存活; - 目的地 `SelectOptionMetadata` 声明了 `color` / `icon` / `disabled` / `visibleWhen`,`@object-ui/fields` 确实在读(`option?.color` 两处); - `@objectstack/spec` 的 `BulkActionParamSchema` 已把同一个 entry 转成 `.passthrough()`(objectstack#4001,维护者裁决 A),服务端照收; - 它自己的父级 `BulkActionParam` 一直有 `[key: string]: unknown` 兜底注释。 于是作者写 `options: [{ label, value, color: '#8B5CF6' }]` 会拿到一个 excess-property 编译错误,而渲染器其实会 honour 它 —— 类型是唯一在拒绝一份能 正常工作的配置的那一层。今天不是运行期 bug,但这是 machine-readable surface 说谎的形状,对绝对信任类型的(AI)作者杀伤最大。 按 #3559(PR #3764)先落地的那一半已经定下的惯用形处理:给 entry 补 `[key: string]: unknown`,注释沿用父级 catch-all 的写法。⛔ 不动 `SelectOptionMetadata`,不把 `objectql.ts` 绑到 `field-types.ts`。**没有**改成 引用 core 的 `ActionParamOption`:`@object-ui/types` 是协议层、不吃 workspace 依赖(AGENTS.md §3 拓扑),因此是结构等价的 inline entry 加一条交叉引用注释。 `label` / `value` 保持必填且类型不变 —— open 不等于 optional;兜底也不是新增 选项键的邀请函,authoring gate 仍是 spec 的严格 `SelectOptionSchema`。 新增 `packages/types/src/__tests__/bulk-action-param-options.test.ts` 钉住四件事: 带 `color`/`visibleWhen` 的 entry 通过编译;`label`/`value` 仍必填(两条必须命中 的 `@ts-expect-error`);entry 经渲染器自己的投影后仍落进 `SelectOptionMetadata` (无需 cast);spec 侧 `.passthrough()` 这个前置事实被断言而非假定。这些钉子是 真会跑的 —— `packages/types/tsconfig.test.json` 编译本包每个测试文件(#3009)。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3309
问题
BulkActionParam.options的 entry 是封闭的{ label, value },而这条路径上其余每一层都不同意它:packages/types/src/objectql.tspackages/plugin-grid/src/components/bulkParamToField.tsoptions?.map(o => ({ ...o, value: String(o.value) }))—— 整体 spread,额外键全部存活packages/types/src/field-types.tsSelectOptionMetadatacolor/icon/disabled/visibleWhenpackages/fields/src/index.tsxoption?.color两处命中,这些键真被读@objectstack/specBulkActionParamSchema.passthrough()(objectstack#4001,裁决 A)BulkActionParam本身[key: string]: unknown兜底(带 catch-all 注释)于是作者写
options: [{ label, value, color: '#8B5CF6' }]会拿到一个 excess-property 编译错误,而渲染器其实会 honour 它。今天不是运行期 bug —— 但类型是唯一在拒绝一份能正常工作的配置的那一层,这正是 machine-readable surface 说谎的形状,对绝对信任类型的(AI)元数据作者杀伤最大。改动
给 entry 补
[key: string]: unknown,注释沿用父级 catch-all 的写法。惯用形不是本 PR 发明的:#3559(PR #3764,已合 main)在一个接口之外走的正是同一条 catch-all 路线(core 导出ActionParamOption),本单照同答案执行。SelectOptionMetadata,没有把objectql.ts绑到field-types.ts。ActionParamOption,尽管两者结构完全一致。@object-ui/types是协议层,按 AGENTS.md §3 拓扑「Zero deps」,不能吃@object-ui/core的依赖(方向也反了 —— core 依赖 types)。因此是结构等价的 inline entry + 一条交叉引用注释,注释里点名ActionParamOption与 objectui#3559,让下一个读者看到的是刻意的并置而不是重复。label/value保持必填且类型不变:open 不等于 optional。注释里也写清了兜底不是新增选项键的邀请函 —— authoring gate 仍是 spec 严格的SelectOptionSchema。用户可见(对 TS 作者而言),已带
@object-ui/types的 patch changeset。前置事实(分诊要求核验,已实读)
objectstack#4001 的
.passthrough()确在 objectstackorigin/main,不是只在 PR 里:packages/spec/src/ui/bulk-action.zod.ts的options为z.array(z.object({ label, value }).passthrough()),describe 文案明写「the renderer forwards unknown option keys to the field widget, which readscolor/icon/disabled/visibleWhenbeyond the declared pair」。本仓node_modules里已安装的@objectstack/spec@17.0.0-rc.5运行期实测也放行并保留了color/visibleWhen(不是 stale install)。钉子(
packages/types/src/__tests__/bulk-action-param-options.test.ts)这些钉子真的会跑:
packages/types/tsconfig.test.json编译本包每一个测试文件(#3009),所以@ts-expect-error与Assert< … >违反时是tsc错误 —— 与@object-ui/core把自己测试排除在tsc之外的情况不同(PR #3764 的同类钉子在头注释里如实记录了那一点)。color/visibleWhen/icon/disabled的 entry 通过编译(能工作的配置现在写得出来);label/value仍必填 —— 两条必须命中的@ts-expect-error(与 fix(app-shell): keep a field's own option keys when an action param inherits them (#3559) #3764 同款);BulkParamOption['color']解析为unknown;声明对Pick< …, 'label' | 'value' >未被放松;{ ...o, value: String(o.value) })后赋给SelectOptionMetadata,无需 cast 即通过 ——objectql.ts自身不 importfield-types.ts,只有测试文件同时 import 两者;.passthrough()这个前置事实被断言而非假定:spec 若哪天回封,这条会失败并指名要复查的层。反向验证(先写预测,再跑)
预测:撤掉索引签名 → 第 1 条与第 3 条转红(excess-property / 属性不存在),第 2 条的两条
@ts-expect-error不受影响(它们钉的是本次不动的声明对)。实测
npx tsc -p packages/types/tsconfig.test.json(已撤销索引签名):方向与预测一致。两处补充说明,如实记录:
authoredOption.color/.visibleWhen,同因转红 —— 预测里没单列,但同向,不构成意外。@ts-expect-error在两个方向都没报错:恢复索引签名后tsc全绿,这本身就证明它们命中了(未命中的@ts-expect-error会以 TS2578 报错);撤销后也未出现在错误清单里。它们对本次改动确实免疫,与预测一致。验证
pnpm --filter @object-ui/types type-check(含tsconfig.test.json)—— 绿。turbo run type-check --filter @object-ui/plugin-grid --filter @object-ui/fields --filter @object-ui/app-shell --concurrency=2—— 31 tasks successful(含整条 build 闭包)。加宽是向后兼容的,亦无exactOptionalPropertyTypes之类意外(仓库根 tsconfig 未开)。vitest run --maxWorkers=2 packages/types/src/__tests__ packages/plugin-grid/…—— 34 files / 451 tests passed。resolveActionParams.test.ts:508/510是 fix(app-shell): keep a field's own option keys when an action param inherits them (#3559) #3764 的ActionParamOption必填钉,同族、不受影响,且在上面的 app-shell type-check 里一并绿)。check-control-bytes(OK)+ 手工grep -naP扫本次三个文件(clean);check-changeset-presence/check-changeset-no-major/check-changeset-fixed全绿;eslint改动文件 0 errors(两条_CatchAll/_DeclaredPairunused 警告与packages/auth/src/__tests__/auth-spec-parity.test.ts的既有惯用形一致,该文件同类警告 23 条)。Generated by Claude Code