mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
`entries.map((entry) => async () => …)` (package-manager's concurrency task lists, `(() => Promise<…>)[]`) was refused: `.map` rejected a `func` return with the same badType as a `void` return. A closure is a supported array element. The closure array literal `[() => 1]` already lowers to a `func`-element array, where the value is one ScrClosure for its whole life, stored by reference with the element kind's `_v` adapter and `scr_closure_trace_v`. The map helper builds the same array, so the `func` half of the fence goes at both `.map` sites (plain receiver and union-of-arrays receiver). The `void` fence stays: `void[]` has no element, because a void return value is erased before it could be written. Corpus 8415-map-closure-elements pins the `.map`-produced arrays of closures: `Array<() => Promise<string>>` and `Array<() => string>`, closure identity through `indexOf`/`includes`, an inline `.map`, and `Promise.all(tasks.map((task) => task()))`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
// `Array.prototype.map` whose callback answers a CLOSURE: the result is an
|
|
// array of functions (`Array<() => Promise<T>>`, the runWithConcurrency
|
|
// task-list shape), each element one ScrClosure stored by reference.
|
|
interface Entry {
|
|
source: string;
|
|
scope: "user" | "project";
|
|
}
|
|
|
|
function tasksFor(entries: Entry[]): Array<() => Promise<string>> {
|
|
return entries.map((entry) => async () => `${entry.scope}:${entry.source}`);
|
|
}
|
|
|
|
function same(entries: Entry[]): Array<() => string> {
|
|
return entries.map((entry) => () => entry.source);
|
|
}
|
|
|
|
async function main(): Promise<void> {
|
|
const entries: Entry[] = [
|
|
{ source: "a", scope: "user" },
|
|
{ source: "b", scope: "project" },
|
|
];
|
|
const tasks = tasksFor(entries);
|
|
for (const task of tasks) console.log("task", await task());
|
|
|
|
const readers = same(entries);
|
|
// A function value is one closure for its whole life: identity through
|
|
// indexOf/includes holds.
|
|
const first = readers[0];
|
|
console.log("identity", readers.indexOf(first!), readers.includes(first!));
|
|
if (first) console.log("called", first());
|
|
|
|
const inline = entries.map((entry) => () => entry.source.length);
|
|
console.log("inline", inline.map((read) => read()).join(","));
|
|
|
|
const results = await Promise.all(tasks.map((task) => task()));
|
|
console.log("all", results.join(","));
|
|
}
|
|
void main();
|