mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-08 08:44:37 +08:00
zod 4 defines its error message with Object.defineProperty(inst, "message",
{ get, set }). The typed-ref commit of an Error subclass read the accessor
as a data value and threw "expected string". The commit and the slot sync
now leave the slot alone and mark the property absent; typed reads and
writes of name and message call the accessor when the program reflects on
an untyped or Error-shaped target.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
// An accessor defined over an Error subclass instance's own `message`
|
|
// (zod 4's lazy error message): typed reads and writes, String(), and
|
|
// reads through an untyped alias all go through the accessor, and a later
|
|
// data definition replaces it.
|
|
class E extends Error {}
|
|
const e = new E("orig");
|
|
let store = "lazy";
|
|
let reads = 0;
|
|
Object.defineProperty(e, "message", {
|
|
get() {
|
|
reads++;
|
|
return store;
|
|
},
|
|
set(value: string) {
|
|
store = `set:${value}`;
|
|
},
|
|
enumerable: true,
|
|
configurable: true,
|
|
});
|
|
console.log(e.message, String(e), reads);
|
|
e.message = "typed";
|
|
console.log(e.message, store);
|
|
const loose: any = e;
|
|
console.log(loose.message);
|
|
loose.message = "loose";
|
|
console.log(e.message, Object.keys(e).join());
|
|
const desc = Object.getOwnPropertyDescriptor(e, "message")!;
|
|
console.log(typeof desc.get, typeof desc.set, desc.enumerable);
|
|
Object.defineProperty(e, "message", { value: "data", writable: true, configurable: true });
|
|
console.log(e.message, String(e), reads);
|
|
e.message = "after";
|
|
console.log(e.message, store);
|
|
|
|
class Named extends Error {}
|
|
const n = new Named("m");
|
|
const loosen: any = n;
|
|
Object.defineProperty(loosen, "name", { get() { return "Custom"; }, configurable: true });
|
|
console.log(n.name, String(n));
|
|
|
|
class Plain extends Error {}
|
|
const p = new Plain("kept");
|
|
p.message = "changed";
|
|
console.log(p.message, String(p));
|