Files
scriptc/tests/corpus/2493-switch-unit-cases.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

51 lines
1.2 KiB
TypeScript

// `case null:` / `case undefined:` over union discriminants: a unit case the union HOLDS is a tag test; a unit case the union LACKS never matches (JS skips it — no coercion of the literal into the union). Grouped unit cases and defaults keep source order.
const items = [1, 2, 3];
const miss = items.find((n) => n > 50);
const hit = items.find((n) => n > 2);
switch (miss) {
case null:
console.log("never: null");
break;
case undefined:
console.log("miss is undefined");
break;
default:
console.log("never: default");
break;
}
switch (hit) {
case null:
console.log("never: null");
break;
case 3:
console.log("hit is three");
break;
default:
console.log("never: default");
break;
}
function tri(flag: number): string | null {
return flag > 0 ? "pos" : null;
}
const triple = tri(-1);
switch (triple) {
case undefined:
console.log("never: undefined");
break;
case "pos":
console.log("never: pos");
break;
case null:
console.log("tri gave null");
break;
}
switch (miss) {
case null:
case undefined:
console.log("grouped unit cases match the undefined arm");
break;
default:
console.log("never: grouped default");
break;
}