Files
scriptc/tests/corpus/class-fetch-handle-fields.ts
T
Malte UblandClaude Opus 5.5 30e23af63f Store fetch Headers, Request, and Response handles in class fields
A class field typed `Headers`, `Request`, or `Response` (or an array or
nullable form of them) maps to checked-dynamic storage, and the class-field
rule refused it (SC1090) although `unknown`, Map values, and closures
already store the same native handles.

Such fields now take the checked-dynamic slot, like the worker handles;
reads keep the handle's identity and the static fetch member lowering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 15:16:17 -07:00

37 lines
1.4 KiB
TypeScript

// Class fields typed as native fetch handles (Headers, Request, Response),
// directly, optional, nullable, in arrays, and inside record fields, hold
// the live handle: mutation through one reference is seen through another.
class Holder {
headers: Headers;
list: Headers[] = [];
maybe?: Response;
req: Request | null = null;
bag: { headers: Headers; status: number };
constructor(headers: Headers) {
this.headers = headers;
this.bag = { headers, status: 1 };
}
}
const holder = new Holder(new Headers({ a: "1" }));
console.log(holder.headers.get("a"), holder.list.length, holder.maybe === undefined, holder.req);
holder.list.push(new Headers({ b: "2" }));
holder.maybe = new Response("x", { status: 201 });
holder.req = new Request("http://localhost/p", { method: "POST" });
console.log(holder.list[0]!.get("b"), holder.maybe.status, holder.req.method, holder.req.url);
holder.headers.set("c", "3");
console.log(holder.bag.headers.get("c"), holder.bag.headers === holder.headers);
// Symbol-keyed fields hold the handles the same way.
const NATIVE = Symbol("native");
class Wrapper {
[NATIVE]: Response;
constructor(body: string) {
this[NATIVE] = new Response(body, { status: 202 });
}
get status(): number {
return this[NATIVE].status;
}
}
const wrapped = new Wrapper("ok");
console.log(wrapped.status, wrapped[NATIVE].headers.get("content-type"));