You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observation-class finding, surfaced by objectui#6421 / PR #6474 (which made isConcurrentUpdateError's narrowed type honest). Recorded, not edited — the fix there was scoped to the predicate's type, and this is about the consumer on the other side of it.
What
packages/plugin-detail/src/InlineEditSaveBar.tsx:124-125 declares the only thing that consumes a narrowed isConcurrentUpdateError result, and types the error as any:
It reads exactly two things off err, both through the any:
err?.currentRecord — line 127, optional-chained and then as-cast to Record<string, unknown> | null. The cast is the only type currentRecord ever gets here; nothing checks it.
err?.currentVersion — lines 135 and 147, optional-chained, flowing straight into the ConcurrentUpdateConflict payload.
The call site one hop up, InlineEditSaveBar.tsx:183, does narrow correctly:
...and then hands the narrowed value to a parameter typed any, which discards it. So the predicate's return type is inert at its only use.
Why it is worth a card
PR #6474 changed the narrowed type from code: 'CONCURRENT_UPDATE' (required, and untrue for the name-limb) to code?: 'CONCURRENT_UPDATE'. The predicate now tells the truth, and nothing is listening. That pin's real-world bite today is smaller than its shape suggests, and the reason is one hop downstream, not in the predicate.
This is the downstream-any species: a type boundary defeated one line after it is drawn. Two siblings already on the backlog, different subjects, same shape — objectui#6459 (ObjectGrid's const dataTableSchema: any means the imported DataTableSchema is never applied) and objectui#5155 (BaseSchema's [key: string]: any).
The decision this needs: should buildConflict take the predicate's narrowed type — which is the point of having a narrowed type at all — or is the any load-bearing for a reason that should be written down? Note that if it does take the narrowed type, the as cast on currentRecord becomes redundant, since the narrowed type already declares currentRecord?: Record<string, unknown> | null.
The "no other consumer" claim, as a measurement
The one-call-site claim is a measurement, not a grep that happened to return one hit. Target, on origin/main:
Positive control 2 — the grep is not blind outside those paths either; it finds the two deliberate sibling copies, which is what a path-scoped zero would otherwise be indistinguishable from:
packages/data-objectstack/src/index.ts (narrows to the class)
packages/plugin-form/src/occSave.tsx (returns bare boolean)
Scope note: this measures in-repo consumers. @object-ui/plugin-detail publishes isConcurrentUpdateError, so an external consumer could be reading the narrowed type; the claim above is about this repository only.
Where
packages/plugin-detail/src/InlineEditSaveBar.tsx:124-125 — the (draft: Record<string, any>, err: any) signature
packages/plugin-detail/src/InlineEditSaveBar.tsx:127 — the as Record<string, unknown> | null cast on err?.currentRecord
Observation-class finding, surfaced by objectui#6421 / PR #6474 (which made
isConcurrentUpdateError's narrowed type honest). Recorded, not edited — the fix there was scoped to the predicate's type, and this is about the consumer on the other side of it.What
packages/plugin-detail/src/InlineEditSaveBar.tsx:124-125declares the only thing that consumes a narrowedisConcurrentUpdateErrorresult, and types the error asany:It reads exactly two things off
err, both through theany:err?.currentRecord— line 127, optional-chained and thenas-cast toRecord<string, unknown> | null. The cast is the only typecurrentRecordever gets here; nothing checks it.err?.currentVersion— lines 135 and 147, optional-chained, flowing straight into theConcurrentUpdateConflictpayload.The call site one hop up,
InlineEditSaveBar.tsx:183, does narrow correctly:...and then hands the narrowed value to a parameter typed
any, which discards it. So the predicate's return type is inert at its only use.Why it is worth a card
PR #6474 changed the narrowed type from
code: 'CONCURRENT_UPDATE'(required, and untrue for thename-limb) tocode?: 'CONCURRENT_UPDATE'. The predicate now tells the truth, and nothing is listening. That pin's real-world bite today is smaller than its shape suggests, and the reason is one hop downstream, not in the predicate.This is the downstream-
anyspecies: a type boundary defeated one line after it is drawn. Two siblings already on the backlog, different subjects, same shape — objectui#6459 (ObjectGrid'sconst dataTableSchema: anymeans the importedDataTableSchemais never applied) and objectui#5155 (BaseSchema's[key: string]: any).The decision this needs: should
buildConflicttake the predicate's narrowed type — which is the point of having a narrowed type at all — or is theanyload-bearing for a reason that should be written down? Note that if it does take the narrowed type, theascast oncurrentRecordbecomes redundant, since the narrowed type already declarescurrentRecord?: Record<string, unknown> | null.The "no other consumer" claim, as a measurement
The one-call-site claim is a measurement, not a grep that happened to return one hit. Target, on
origin/main:Four lines: one definition, one re-export, one import, one call site.
Positive control 1 — the identical grep shape over the identical paths, for a symbol known to have many consumers, returns 54 lines:
Positive control 2 — the grep is not blind outside those paths either; it finds the two deliberate sibling copies, which is what a path-scoped zero would otherwise be indistinguishable from:
Scope note: this measures in-repo consumers.
@object-ui/plugin-detailpublishesisConcurrentUpdateError, so an external consumer could be reading the narrowed type; the claim above is about this repository only.Where
packages/plugin-detail/src/InlineEditSaveBar.tsx:124-125— the(draft: Record<string, any>, err: any)signaturepackages/plugin-detail/src/InlineEditSaveBar.tsx:127— theas Record<string, unknown> | nullcast onerr?.currentRecordpackages/plugin-detail/src/InlineEditSaveBar.tsx:135,:147—err?.currentVersionpackages/plugin-detail/src/InlineEditSaveBar.tsx:183— the narrowing that is then discardedpackages/plugin-detail/src/ConcurrentUpdateDialog.tsx:223— the predicate whose narrowed type PR fix(plugin-detail): declarecodeoptional in isConcurrentUpdateError's narrowed type #6474 correctedFiled flat, ungraded — no user-visible symptom and no test moves either way.
Generated by Claude Code
Generated by Claude Code