Closed as not planned
Description
Bug Report
π Search Terms
- Truthiness narrowing
- Truthiness narrowing with &&
- Truthiness narrowing with other conditional expressions
- Narrowing
- Control flow analysis
π Version & Regression Information
Possibly related to #52272
β― Playground Link
Playground link with relevant code
π» Code
interface Circle {
kind: "circle";
x: number;
}
interface Square {
kind: "square";
x: number | null;
}
type Shape = Circle | Square;
function fn1(shape: Shape) {
if (shape.kind === "square" && shape.x === null) {
const { kind, x } = shape // { kind: "square", x: number } as expected
return
}
// After the conditional branch above, we know that `shape.x` can no longer
// be `null`.
if (shape.kind === "square") {
const { kind, x } = shape // { kind: "square", x: number | null }
// type of `x` should be `number` only
}
const newKind = shape.kind // type is `"circle" | "square"` as expected
const newX = shape.x // type of `shape.x` should be narrowed to `number` only
}
function fn2(shape: Shape) {
// it works when we narrow the type without other conditonal expressions
if (shape.x === null) {
const { kind, x } = shape // { kind: "square", x: number } as expected
return
}
if (shape.kind === "square") {
const { kind, x } = shape // { kind: "square", x: number } as expected
}
const newKind = shape.kind // type is `"circle" | "square"` as expected
const newX = shape.x // type is `number` only as expected
}
π Actual behavior
TypeScript fails to narrow the type of shape.x
to number
only in fn1
after the first conditional branch if (shape.kind === "square" && shape.x === null)
π
π Expected behavior
After the first conditional branch if (shape.kind === "square" && shape.x === null)
in fn1
, shape.x
can not be null
anymore.
However, doing just if (shape.x === null)
in fn2
works fine