Files
scriptc/tests/corpus/6493-runtime-key-destructuring.cjs
T
Chris Tate 9baa93b799 Keep missing runtime-key entries undefined at module scope, and check nullish sources before runtime keys
- The indexed-read prepass now treats a computed pattern key like the name it folds to, and a runtime key over a record with no declared fields as an index-signature read. A module-scope binding from a missing entry (`const { [name]: v } = table` over `Record<string, number>`) now holds undefined instead of throwing a TypeError.
- An object pattern over a checked-dynamic value whose first key is computed at run time checks the source first. A null or undefined source throws a TypeError before the key's expression runs, as in Node. In JavaScript declarations whose source V8 can spell, the message is Node's ("Cannot destructure 'f(...)' as it is null.").
- Corpus 6492 adds a module-scope missing entry; 6493 adds nullish sources in front of side-effecting keys, including a nested pattern and an element default.
- The retired-engine-2104 diagnostics snapshot drops the refusals of `const { [key]: got } = src` over an `any` source, which now compile. The remaining refusals are unchanged.
2026-10-20 18:34:42 -05:00

61 lines
1.6 KiB
JavaScript

"use strict";
// Runtime computed keys in object patterns over JavaScript values: the
// live property is read, undefined when absent, including nested patterns
// over a typed module object (`const { signals: { [name]: n } } = os.constants`).
const os = require("os");
const table = [
{ name: "SIGINT", number: 2 },
{ name: "SIGTERM", number: 15 },
{ name: "SIGNOPE", number: 99 },
];
function resolve({ name, number: fallback }) {
const {
signals: { [name]: constant },
} = os.constants;
const supported = constant !== undefined;
return `${name}:${supported}:${supported ? constant : fallback}`;
}
console.log(table.map(resolve).join(" "));
function lookup(source, field) {
const { [field]: value = "none", [`${field}Count`]: count } = source;
return `${field}=${value}/${count}`;
}
const record = { color: "red", colorCount: 3, size: 4 };
console.log(lookup(record, "color"), lookup(record, "size"), lookup(record, "shape"));
// A nullish source throws before a runtime first key is evaluated.
let keyCalls = 0;
function keyOf(name) {
keyCalls++;
return name;
}
const nothing = () => JSON.parse("null");
const flag = process.argv.length > 99;
for (const attempt of [
() => {
const { [keyOf("a")]: v } = nothing();
return v;
},
() => {
const { [keyOf("a")]: v = 1 } = flag ? nothing() : undefined;
return v;
},
() => {
const { a: { [keyOf("b")]: v } } = JSON.parse('{"a":null}');
return v;
},
]) {
try {
attempt();
} catch (e) {
console.log(e instanceof TypeError, keyCalls);
}
}
try {
const { [keyOf("a")]: v } = nothing();
console.log(v);
} catch (e) {
console.log(e.message, keyCalls);
}