mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
A union may now hold one promise beside data members (`T | Promise<T>`, `Promise<R | void> | R | void`). The union tag is the `instanceof Promise` test, and every operation keeps Node's microtask timing: `await` awaits the promise arm or takes the one non-thenable turn, an async `return` (block bodies, concise arrows, then handlers) adopts the promise arm after the function's own finally blocks, `Promise.resolve` returns the promise arm as is, and `typeof (u as any).then` reads the tag. Data arms that declare `then`, two promise arms, and function arms beside a promise stay refused with diagnostics. Inferred JavaScript literals that mix promises and values keep the checked-dynamic array. Rest parameters typed `unknown[]` or `any[]` in TypeScript use the checked-dynamic variadic ABI that JavaScript rest parameters already use, including spread forwarding (`(...args) => handler(...args)`). Functions are now Map values, Map keys and Set elements, compared by closure identity. Two pre-existing bugs in the same area are fixed: an async lambda in a `Promise<void> | void` slot got a `Promise<union>` ABI and threw when called through the slot, and `return cb()` of such a callback in an async function dropped the promise instead of adopting it. The retired-engine 2251 and 2790 diagnostics fixtures (tagged templates with `any[]` rest tags) now compile and match Node, so they move to the corpus as 6248 and 6249. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
// SC2009: supported shapes over a component type outside its slot — the
|
|
// container is not the blocker, and each message names the component.
|
|
|
|
// Boolean Map keys remain outside the supported key domain.
|
|
const byFlag = new Map<boolean, string>();
|
|
console.log(byFlag);
|
|
|
|
// Map values have no slot for Dates.
|
|
const stamps = new Map<string, Date>();
|
|
console.log(stamps);
|
|
|
|
// Boolean Set elements remain outside the supported element domain.
|
|
const flags = new Set<boolean>();
|
|
console.log(flags);
|
|
|
|
// Arrays hold Map elements; retain the accepted adjacent form.
|
|
const rows: Map<string, number>[] = [];
|
|
console.log(rows);
|
|
|
|
// Nullable Maps compile and remain as working context.
|
|
function report(maybe: Map<string, number> | undefined): number {
|
|
return maybe === undefined ? 0 : maybe.size;
|
|
}
|
|
console.log(report(undefined));
|
|
|
|
// Typed rest values now compile; retained here as working context for the
|
|
// component-type failures below.
|
|
const sum = (...xs: number[]): number => xs.length;
|
|
const storedSum = sum;
|
|
console.log(storedSum(1, 2));
|
|
|
|
// A function's return type carries the failure. The value arrives through
|
|
// a cast, not an ambient declare (a declare-rooted chain would compile to
|
|
// Node's ReferenceError at the root instead).
|
|
const makeWeak = (0 as unknown) as () => WeakRef<object>;
|
|
const storedMake = makeWeak;
|
|
console.log(storedMake());
|
|
|
|
// A record member's type carries the failure.
|
|
interface Holder {
|
|
label: string;
|
|
cache: WeakRef<object>;
|
|
}
|
|
const held = (0 as unknown) as Holder;
|
|
const kept = held;
|
|
console.log(kept.label);
|