Files
scriptc/tests/corpus/2494-no-arm-compare-effects.ts
Chris Tate 8d2b3bb2e0 No-arm unit comparisons answer constants instead of trapping
- lowerUnitComparison folds ===/!== against a union lacking the unit arm to the constant answer, both operand orders
- a non-droppable operand still evaluates exactly once, riding a throwaway tag test
- union-switch case null / case undefined take the unit-comparison lowering, so a lacking arm never matches
- the unionEq fallback had coerced the literal through the stranded-arm trap, throwing where Node answers false
- corpus 2490-2494: the find-miss repro, every strict and loose spelling, switch unit cases, effect preservation
2026-07-23 14:34:41 -05:00

27 lines
859 B
TypeScript

// The no-arm unit comparison still EVALUATES its operand: `xs.find(probe) === null` runs the probe callbacks (JS evaluates both sides of ===), the answer is the constant, and `??` on `T | undefined` / `T | null` takes the default on exactly its own unit arms.
let calls = 0;
const xs = [1, 2, 3];
const probe = (x: number): boolean => {
calls++;
return x > 10;
};
console.log(xs.find(probe) === null);
console.log(calls);
console.log(xs.find(probe) !== null);
console.log(calls);
console.log(null === xs.find(probe));
console.log(calls);
function pick(): number | undefined {
calls += 100;
return undefined;
}
console.log(pick() === null, calls);
console.log(pick() ?? -1);
function pickNull(): string | null {
calls += 1000;
return null;
}
console.log(pickNull() === undefined, calls);
console.log(pickNull() ?? "fallback");
console.log(calls);