Files
scriptc/tests/corpus/2539-class-instance-rest.ts
T
Chris Tate 385b0a9199 Promote destructuring assignment targets, class-instance sources, class rest, and accessor defaults to the static tier
- Destructuring assignment now takes nested patterns (`({ p: { q } } = src)`, `[[a], b] = t`) and property/element targets (`[c.x, box.vals[i]] = arr`, `({ a: rec.f } = o)`, rest into members) — receivers temp at their pattern position, JS's reference-before-read order; defaults on member targets test against the target's own type. Defaults on nested targets keep a named fence (no single binding type to test against).
- Class instances destructure in assignment position like they already did in declarations: field slots and getter calls per element via the same fieldGetExpr dispatch, defaults, renames, and member targets; methods and undeclared names keep their pointed fences.
- Rest over class-instance sources packs the remaining instance FIELDS into a fresh record (JS's CopyDataProperties copies own enumerable properties — never prototype methods/accessors, matching the checker's rest type), in declarations and assignments; non-public fields, runtime-provided chains (Error/EventEmitter/stream), and key orders the packed shape cannot reproduce fence instead of diverging.
- Defaults on destructured getter results now lower (record and class accessors alike), with the getter result temped so the default's undefined test never calls it twice; numeric-literal pattern keys (`const { 2: x } = o`) fold to JS's canonical property name.
- Corpus 2536-2540 pin the new forms byte-identically against Node on both backends; the destructuring-fences diagnostics program keeps the honest residue (method extraction, non-public rest fields, nested-target defaults, index-signature rest).
- The ts7 order-parity baseline re-record backfills the entries the released file was missing (2490-2500 included) alongside the new fixtures; no existing entry changed.
2026-07-23 17:27:25 -05:00

59 lines
1.7 KiB
TypeScript

// @transform-types
// Rest properties over CLASS-INSTANCE sources: the remaining instance
// FIELDS pack into a fresh record — never the prototype members
// (methods and accessors stay behind, exactly JS's CopyDataProperties
// over own enumerable properties) — in declarations and assignments,
// with Node's key order and freshness.
class Point {
x = 1;
y = 2;
z = 3;
norm(): number {
return this.x + this.y + this.z;
}
get sum(): number {
return this.norm();
}
}
const { x, ...restXY } = new Point();
console.log(x, restXY.y, restXY.z);
console.log(JSON.stringify(restXY), Object.keys(restXY).join(","));
// Methods and getters never join the rest object.
const p2 = new Point();
const { y, ...others } = p2;
console.log(y, JSON.stringify(others));
// The copy is fresh: writes through it never reach the instance.
others.x = 99;
console.log(p2.x, others.x);
// Renamed siblings consume their SOURCE field.
const { z: depth, ...flat } = new Point();
console.log(depth, JSON.stringify(flat));
// Inherited fields join the rest (base fields enumerate first, like
// Node's property-creation order).
class Tagged extends Point {
tag = "t";
}
const { tag, ...coords } = new Tagged();
console.log(tag, JSON.stringify(coords));
// Constructor-assigned and parameter-property fields are instance
// fields too.
class Sized {
readonly unit: string;
constructor(public w: number, public h: number) {
this.unit = "px";
}
}
const { unit, ...dims } = new Sized(4, 5);
console.log(unit, JSON.stringify(dims));
// Assignment position packs identically.
let keep = 0;
let restAssign: { y: number; z: number } = { y: 0, z: 0 };
({ x: keep, ...restAssign } = new Point());
console.log(keep, JSON.stringify(restAssign));