Files
scriptc/tests/corpus/generic-member-lambda-impls.ts
T
Malte UblandClaude Opus 5.5 3375304945 Erase lambdas that implement a generic method through their context
A lambda with no type parameters of its own, contextually typed by a
generic signature (`send: (m) => …` for an interface's `send<T>(m:
Message<T>): string`), takes that signature's type parameters: its
parameter is `Message<T>`. A generic lambda written with its own type
parameters already lowers once, erased, with them bound to `unknown`, but
this one tried to map `Message<T>` with `T` unbound and was refused
(SC2009).

It now lowers the same way, erased, binding the contextual signature's
type parameters to `unknown`. Parameters bound in the enclosing scope
keep their bindings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 15:02:24 -07:00

41 lines
1.4 KiB
TypeScript

// An object literal implements an interface's generic method with a plain
// lambda (`send: (m) => …` for `send<T>(m: Message<T>): string`). The
// lambda takes the contextual signature's type parameters as its own and
// lowers once, erased, like a generic lambda: its parameters hold whatever
// each call passes.
interface Message<T = unknown> {
content: string;
details?: T;
}
interface Sender {
name: string;
send<T = unknown>(message: Message<T>): string;
notify<T>(message: Message<T>): void;
pick<K extends string>(keys: K[], fallback: K): K;
}
const log: string[] = [];
function makeSender(name: string): Sender {
return {
name,
send: (message) => `${name} sent ${message.content} (${message.details === undefined ? "no details" : JSON.stringify(message.details)})`,
notify: (message) => {
log.push(`${name} notified ${message.content}`);
},
pick: (keys, fallback) => keys[0] ?? fallback,
};
}
const senders: Sender[] = [makeSender("first"), makeSender("second")];
for (const sender of senders) {
console.log(sender.send({ content: "hi", details: { n: 3 } }));
console.log(sender.send({ content: "bare" }));
console.log(sender.send<number[]>({ content: "list", details: [1, 2] }));
sender.notify({ content: "ping", details: true });
console.log(sender.pick(["a", "b"], "z"), sender.pick([], "z"));
}
console.log(log.join("; "));