Files
scriptc/tests/coverage-fixtures/width-copies.ts
T
Malte Ubl 8f5ec2d94f Report record width copies at assertions, assignments and array elements
SC6001 only looked at call arguments and typed initializers, and only at
strict field subsets: a target that adds optional properties, the empty
record type, `r as T`, a later `v = r` into a typed binding, and records
stored as elements of a typed array literal copied silently.

The scan now reports a copy whenever the property sets differ, covers
those sites, and reports a class instance that reaches a plain record
type which does not keep its identity (the remaining boundary: interfaces
of only generic methods). Every corpus program still reports no
divergence.
2026-10-16 14:02:02 -07:00

40 lines
1.1 KiB
TypeScript

// Record width copies beyond parameters and typed initializers: each site
// stores a record in a narrower or differently shaped record type, and the
// program then writes through or compares the copy.
interface Labeled {
label: string;
}
interface Tagged {
label: string;
tag: string;
}
interface Noted {
label: string;
note?: string;
}
const tagged: Tagged = { label: "first", tag: "t" };
// A target that adds an optional property is a different shape: a copy.
function annotate(target: Noted): void {
target.label = "noted";
}
annotate(tagged);
// The empty record type keeps no property, and no identity either.
const anything: {} = tagged;
console.log(anything === tagged);
// An assertion to a narrower record type copies as well.
const asserted = tagged as Labeled;
asserted.label = "asserted";
// So does a later assignment to a binding declared with that type.
let later: Labeled = { label: "later" };
later = tagged;
later.label = "assigned";
// Array elements are stored as copies of the element type.
const list: Labeled[] = [tagged];
for (const item of list) item.label = "element";
console.log(tagged.label);