mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-13 04:30:16 +08:00
- ambientUndefVarRootOf walks calls, `new`, optional chains, assertions, instantiation expressions, and tagged templates, and accepts `declare function` and trap-binding roots: Node erases the declaration, so the root read IS the crash — lowerCall, member reads, assignments, and variable declarations lower the whole statement to the catchable ReferenceError, arguments never evaluate, and the never-initialized binding registers as a trap whose references can never run
- never-read unmappable bindings with value-only initializers and writes emit nothing: Node builds the value and drops it, so `var xs2: typeof Array;` and the write-only `var f2: { <T, U>(x: T, y: U): T }` compile instead of fencing on a type the program never consumes
- null!/as-any bindings whose types keep generic signatures (or intern empty record shapes) register no storage; generic-method calls and member reads through them compile to Node's exact TypeError, nullish-to-nullish flows to nothing, heritage-clause uses decline the family so mixin resolution keeps its fence, and checked-dynamic (`any`) bindings keep their dyn story untouched
- assertion-shaped generic arrows (`< <T>(x: T) => T >((x) => x)`) register like annotated bindings and monomorphize per call; stdlib generic members (Promise.then, Object.defineProperty) take the SC2020 lib fence, and Function.prototype.apply/call/bind on compiled function values name the direct-call spelling
- diagnostics fixtures that used `declare` to conjure unconstructible values now conjure them by cast so each fence family keeps its pin; snapshots re-recorded, the deferred checker-panic diagnostic now flushes at its first reference as designed
19 lines
765 B
TypeScript
19 lines
765 B
TypeScript
// SC2007: values of overloaded function type — a compiled function VALUE is
|
|
// one concrete signature. Calls of overloaded declarations resolve per call
|
|
// site; it is the value position that fences.
|
|
|
|
function pick(x: "a"): string;
|
|
function pick(x: "b"): number;
|
|
function pick(x: string): string | number {
|
|
return x === "a" ? "A" : 1;
|
|
}
|
|
const stored = pick;
|
|
console.log(stored("a"));
|
|
|
|
// An overloaded TYPE LITERAL slot fences the same way. 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 on = ((() => {}) as unknown) as { (event: "exit", code: number): void; (event: "error", err: string): void };
|
|
const listener = on;
|
|
console.log(listener("exit", 0));
|