Uh oh!
There was an error while loading. Please reload this page.
docs(plugin-form): README 的 Schema API 与 Examples 按 form 真读的键面重写 - #5100
Merged
Conversation
三组连体键面漂移,一次改对(#5075 的三组读数逐条复测通过,另修正两处计数)。 判据一律取构建产物 `dist/index.d.ts` 在 strict 下的真编译。 1. `validation` 写成 `[{ type, value, message }, …]` 三处 —— 真身是 `FormField.validation?: FieldValidationRules`,按规则名开键的**对象** (`types/src/form.ts:744`)。类型侧 TS2559 ×3;运行时侧是**静默**的,这是本 组最要紧的一半:唯一读点 `components/src/renderers/form/form.tsx:1652` 写的是 `const rules: any = { ...validation }`,把数组展开进对象字面量得到 `{ '0': …, '1': … }`,而 react-hook-form 的字段校验器只解构 required/maxLength/minLength/min/max/pattern/validate/valueAsNumber —— README 教出来的规则一条不跑且零报错。顺带写进两条读者猜不到的事实: `validation.required` 只提供**消息**(是否必填由字段自身的 required / requiredWhen 决定),手写的 `pattern.value` 必须给 RegExp(RHF 只应用 `value instanceof RegExp` 的 pattern;把声明的 string 编译成正则的是元数据 路线的 `buildValidationRules`)。 2. `type: 'multi-step-form'` 全仓未注册,`steps` 也不是任何 form schema 的键 (`types/src` 零声明,`.steps` 的读点全是 flow 执行日志)—— 整个示例渲染出 未知组件占位,`steps` 里的字段从不被读。改教两个真实入口:`object-form` + `formType: 'wizard'`(步骤即 `sections`,`ObjectForm.tsx:255` 的路由),以及 导出的 `WizardForm` 配 section 内联字段、无 dataSource(`onSuccess` 而非 `onSubmit`)。⛔ 未注册任何新 type 去把旧拼法变真。 3. `FormField` 参考块现场声明了一个本地 `interface FormField` —— 裸声明永远编译 通过。五行是错的(`type`/`label` 是**可选**;`validation` 见上; `defaultValue`/`className` 不是声明键),`ValidationRule` 这个类型名全仓不 存在,且 23 个真键只列了 7 个。改为对真身声明的键表 + `FormSchema` 键表,示例 逐块标注真类型 —— 标注本身就是要点:`FormField` 与 `BaseSchema` 都带 `[key: string]: any`,不带标注的 `const schema = { … }` 写什么都能过编译, 发明的键也永远不是编译错误。 卡面两处计数如实修正:缺席的真键是 **16** 个(卡面列了 15,漏了 `inputType` —— README 自己的示例在用它);「五处漂移」里的 `defaultValue`/`className` 两条 无法由探针证明,只能由声明缺席 + 读点 grep 证明(见 PR 正文的分层)。 纯文档改动:不改渲染器行为,不动 form.tsx 的读点,未新增任何能力、导出或类型。 Fixes#5075 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 18, 2026
CollaboratorAuthor
PM 验收:ACCEPT(session_01GTRjn8xBqp75dk7kFupVRt,objectui 分片) 实物核验:merge-base 验收要点:
三件套照常:本评论 → undraft → auto-merge(SQUASH)。 Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 18, 2026 00:07
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 18, 2026
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 freeto 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#5075
packages/plugin-form/README.md的## Schema API与## Examples两节整段重写。三组是连体的:只改参考块、留着两个示例继续教validation: [ … ],同一个 README 会自相矛盾。纯文档改动 —— 不改渲染器行为,不动form.tsx的读点,未新增任何能力、导出或类型。基线
origin/main=9fbb9b52ffa92432019a9a5ebfdd6a671d891f77。前提门:卡面三组读数逐条复测
validation: [ … ]FieldValidationRules是按规则名开键的对象(types/src/form.ts:744)components/src/renderers/form/form.tsx:1652的{ ...validation }multi-step-form全仓仅该 README 命中plugin-form/src/index.tsx:100 / :159 / :211 / :232 / :276 / :356)steps不在FormSchema上packages/types/src零声明,全仓.steps读点全是 flow 执行日志(app-shell / console),与表单无关FormField真身 23 键(form.ts:898)defaultValue、className本就不是真键;卡面的缺席清单漏了inputType,而 README 自己的示例一直在用它type/label可选性与validation形由编译探针证明;defaultValue/className不能由探针证明(见「探针有牙 / 致盲」)三组判定表
1 ·
validation数组拼法 → 真身对象形validation: [{ type: 'email', … }](Basic Form)FieldValidationRules无email规则名pattern,正则取buildValidationRules对type === 'email'字段发出的同一条validation: [{ type: 'minLength', value, message }, …](Form with Validation ×2)minLength?: { value: number; message: string }等按名开键message手写时不是可选的validation?: ValidationRule[](参考块)validation?: FieldValidationRules{ type: 'pattern', value: '^…$' }的 string 正则validation.required只提供消息required/requiredWhen决定(form.tsx:1704只把它当 message,presence 来自resolveFieldRuleState)2 ·
multi-step-form/steps→ 真实入口type: 'multi-step-form'object-form+formType: 'wizard'(ObjectForm.tsx:255的路由,条件是formType === 'wizard' && sections?.length)steps: [{ title, fields }]steps键sections,每 section 一步;ObjectFormSection.fields收(string | FormField)[]FormField直通(sectionFields.ts:164)WizardForm+ 内联字段,dataSource省略onSubmitWizardFormSchema上没有这个键;无 dataSource 时回调是onSuccess(WizardForm.tsx:485)onSuccessmobile: { stepper }的扁平表单自动分步(ObjectForm.tsx:1279),避免读者重新发明⛔ 未注册任何新 type、未新增任何键去把旧拼法变真。
3 ·
FormField参考块 → 真身 23 键type: string(必填)type?: string'input'label: string(必填)label?: stringname)—— 卡面未涉及,按读点如实写validation?: ValidationRule[]validation?: FieldValidationRulesValidationRule这个名全仓不存在defaultValue?: anyFormSchema.defaultValuesclassName?: stringspan/colSpan,栅格是FormSchema.fieldContainerClass。口径:字段级className确有一个读点,但只在type: 'section-divider'这个伪字段上(form.tsx:1646),README 如实标注iddescriptioninputTypewidgetoptionsconditionvisibleOnvisibleWhenreadonlyWhenrequiredWhendependsOnhiddenreadonlyfieldcolSpanspan参考块不再现场声明本地
interface FormField(裸声明永远编译通过,正是本次漂移的成因),改为对真身声明的键表 +FormSchema键表,示例逐块标注真类型。静默失效:前提复现
第 1 组最要紧的一半是运行时静默,而不是类型红。机制复现(node,零 React):
react-hook-form 7.85.0 的字段校验器只解构固定集合(
dist/index.cjs.js):数字键不在其中 —— README 教出来的 email / minLength / maxLength / pattern 一条不跑,且没有任何报错。照抄的表单看上去有校验,实际没有。
顺带同一读点的另一面(已另立 #5099,本 PR 不动代码):
pattern.value写 string 也是静默失效 —— RHF 只应用value instanceof RegExp的 pattern(Z=e=>e instanceof RegExp),把声明的 string 编译成正则的只有元数据路线的buildValidationRules(fields/src/index.tsx:2303)。README 因此教 RegExp 字面量。探针有牙 / 致盲(先实测,再声称)
探针一律对构建产物
dist/index.d.ts,strict,逐块单文件编译。有牙(声明键的类型压过索引签名):
validation: [ … ]标注FormSchemaTS2559: Type '{ type: string; message: string; }[]' has no properties in common with type 'FieldValidationRules'×3type: 'multi-step-form'标注FormSchemaTS2322: Type '"multi-step-form"' is not assignable to type '"form"'TS2322 … Types of property 'type' are incompatible … Type 'string | undefined' is not assignable to type 'string'{ name; label }TS2322 … 'label' … 'string | undefined' is not assignable to 'string'const f: FormField = {}TS2741: Property 'name' is missing——name是唯一必填键TS2322 … 'validation' … 'DocValidationRule[]' has no properties in common with type 'FieldValidationRules'致盲(实测确认,不冒充键面证据):
steps: [ … ]挂在FormSchema上FormSchema extends BaseSchema,base.ts:318有[key: string]: any{ name: 'x', defaultValue: 'draft' }标注FormFieldFormField自带[key: string]: any(form.ts:1034){ name: 'x', className: 'col-span-2' }标注FormField所以
steps/defaultValue/className三条只由「声明缺席 + 读点 grep」证明,PR 与 README 都按这个口径写。反面对照:WizardFormSchema没有索引签名,标注它的示例里发明一个键就是真编译错误 —— README 也把这条差别写下来了。改后:两个 after 探针(重写后的 Basic / Validation / 两条 wizard 示例,含
WizardFormProps省略dataSource)rc=0。反向验证(预判先写,实测在后)
TS2559×3(见上)。validation形,对type/label被写成必填沉默 —— 更严格的源赋给更宽松的目标本就合法,这一向结构上看不见「文档过度必填」。与预判一致(plugin-grid README 教gridComponents手动注册与GridSchema/GridColumn类型 —— 前两者不存在,GridSchema这个名字在 types 里是 CSS Grid #5013 家族形)。type可选性。validation改回数组、optionality 修好):也报validation(FieldValidationRules is missing the following properties from type 'DocValidationRule[]': length, pop, push …)。所以两向并不是「各自独占一个事实」:TS 每个赋值只报第一个不相容属性,覆盖面取决于属性顺序。双向仍然必要(方向 2 看不见过度必填),但理由是这个,不是模板预设的「一向一事实」。名集合核对(#5043 规格)
对 README 的全部代码块做 AST 解析,收集 import 绑定与类型引用,逐个对构建产物的真实导出集合核验:
门禁
pnpm exec turbo run type-check --concurrency=2(仓根,经 flock)Tasks: 81 successful, 81 total,rc=0node scripts/check-doc-links.mjsLinks are valid across 13 scan roots.node scripts/check-control-bytes.mjsOK (scanned 4525 tracked text file(s))grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]'范围
只动
packages/plugin-form/README.md+ 一个 changeset(@object-ui/plugin-formpatch,docs 级)。与在飞 #5066 / #5062 / #5063 零交集。实施中扫出、未夹带进本 PR 的两条,已另立卡:
## Integration with Data Sources一节把dataSource/resource写在 form schema 上,两键全仓零读取点(真机制是SchemaRendererContext,本 README 别处已写对,属自相矛盾)。不在本卡三组之内。FieldValidationRules在唯一读点既不校验也不归一:pattern.value写成 string(类型明确允许)被 react-hook-form 静默忽略,未识别的规则名同样静默丢弃 #5099 —— 手写FieldValidationRules在唯一读点既不校验也不归一:pattern.value写 string(类型明确允许)被 RHF 静默忽略,未识别的规则名同样静默丢弃。改法涉及公开类型/渲染器,附两方案与推荐,交维护者定。Generated by Claude Code