mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
A written type predicate usually names FEWER members than the
receiver's element has — `(c): c is { text: string } => ...` over a
block that also carries a `textSignature` — and may name a structural
type that is no arm of the element union at all. Both shapes refused,
so `commitments.filter(pred)` over a union of records with differing
members did not compile.
Record targets now convert when their members are a SUBSET of the
source's: each target member is read and converted, the copy keeps the
source's keys in the source's order, and a member the source lacks
still has no slot to read and stays refused.
When no union arm matches the predicate's type, `structuralUnionConversion`
converts tag by tag: each arm the target can be read from returns its
converted value and an arm with no such read throws the same checked
TypeError a lying predicate throws, so the checked extraction still
traps rather than silently passing a foreign value through.
Corpus 8524 pins the subset-record and structural-union conversions;
`narrow-guard-traps.test.ts` pins the TypeError a predicate that
returns true for a foreign value raises.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>