Files
scriptc/tests/diagnostics/spi-off/main.ts
Chris Tate fc84780ebe Deferred-init fields: stream!-style classes lower with typed extraction reads
- a !-asserted (or SPI-off) field first assigned past the constructor's top level rides an undefined-armed union slot: allocation writes the interned undefined, writes wrap, reads extract the declared type
- scalar reads take unit defaults where JS-undefined behavior survives (bool false, f64 NaN — conditions and arithmetic exact); string/ref reads keep the checked-extraction trap, JS's own first-member-use TypeError named earlier
- union/map/dyn-typed ! fields keep the fence; deferral propagates down the base chain with the fields map
- diagnostics fixtures re-pin the surviving fences; corpus 2429 pins the Output.initialize idiom on both backends; SEMANTICS.md 372-375
2026-07-23 00:40:54 -05:00

36 lines
971 B
TypeScript

// A project tsconfig with strictPropertyInitialization OFF (strict: false;
// strictNullChecks stays on — the floor): tsc no longer verifies that
// initializer-less fields are assigned in the constructor. An
// unconditionally ctor-assigned field compiles as ever (`Ok`); a field
// assigned only in a method now DEFERS like a `!` assertion (the slot
// rides `T | undefined`, reads extract — SEMANTICS.md 372), so `Bad`
// compiles too. The fence survives exactly where the deferral cannot
// carry the type: a MAP-typed field (map arms cannot join a union).
class Ok {
n: number;
s: string;
constructor(n: number) {
this.n = n;
this.s = "ok";
}
}
class Bad {
v: number; // compiles: deferred init (reads NaN until assigned)
m(): void {
this.v = 1;
}
}
class Worse {
m: Map<string, number>; // fenced: no deferral union for map fields
fill(): void {
this.m = new Map();
}
}
console.log(new Ok(5).n);
new Bad();
new Worse();