mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
- 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.
67 lines
1.4 KiB
TypeScript
67 lines
1.4 KiB
TypeScript
// Destructuring assignment FROM class instances: field reads, getter
|
|
// calls at the element's pattern position, inherited members, defaults
|
|
// against the target's own type, renames, and member targets fed from a
|
|
// class source.
|
|
class Base {
|
|
root = "r";
|
|
}
|
|
class Item extends Base {
|
|
id = 7;
|
|
label = "seven";
|
|
get loud(): string {
|
|
return this.label.toUpperCase();
|
|
}
|
|
}
|
|
const item = new Item();
|
|
|
|
let id = 0;
|
|
let label = "";
|
|
({ id, label } = item);
|
|
console.log(id, label);
|
|
|
|
// Renames and getters.
|
|
let shout = "";
|
|
let from = "";
|
|
({ loud: shout, root: from } = item);
|
|
console.log(shout, from);
|
|
|
|
// Defaults from undefined-armed class fields.
|
|
class Sparse {
|
|
hit?: number;
|
|
miss?: number;
|
|
constructor() {
|
|
this.hit = 3;
|
|
}
|
|
}
|
|
let hit = -1;
|
|
let miss = -1;
|
|
({ hit = -10, miss = -20 } = new Sparse());
|
|
console.log(hit, miss);
|
|
|
|
// A class source feeding MEMBER targets.
|
|
const sink = { a: 0, b: "" };
|
|
({ id: sink.a, label: sink.b } = item);
|
|
console.log(sink.a, sink.b);
|
|
|
|
// Getters run ONCE per element, at the element's position.
|
|
const order: string[] = [];
|
|
class Tracked {
|
|
get first(): number {
|
|
order.push("first");
|
|
return 1;
|
|
}
|
|
get second(): number {
|
|
order.push("second");
|
|
return 2;
|
|
}
|
|
}
|
|
let f = 0;
|
|
let sec = 0;
|
|
({ second: sec, first: f } = new Tracked());
|
|
console.log(order.join(","), f, sec);
|
|
|
|
// Expression-position class-source assignment keeps the RHS value.
|
|
let again = 0;
|
|
const same = ({ id: again } = item);
|
|
console.log(again, same.label);
|