Skip to content

v4.1.4

Compare
Choose a tag to compare
@gvergnaud gvergnaud released this 06 Feb 23:34
· 286 commits to main since this release

Bug fixes

Issue #138 β€” inference issues with P.not

When using P.not with a literal value like P.not(2), Exhaustive checking was mistakenly considering that all numbers had been handled, even though 2 isn't. This was causing this code to erroneously type-check:

match<number>(input)
        .with(P.not(10), () => 'not video of 10 seconds.')
        .exhaustive() // This type-checked even though the value `10` isn't handled

This new patch version fixes this bug.

Caveats

Exhaustive pattern-matching expressions where the input is a primitive (like number) and the pattern is a negation of a literal number (like P.not(2)) are no longer considered exhaustive:

match<number>(1)
  .with(P.not(2), () => 'not 2')
  .with(2, () => '2')
  .exhaustive(); // ❌ `number` isn't handled

Technically, this expression is exhaustive but there is no easy way to type-check it is without negated types (microsoft/TypeScript#29317), so this is an expected false-positive for now.

Exhaustive checking works as expected when the pattern and the input are primitive types:

match<number>(1)
  .with(P.not(P.number), () => 'not 2')
  .with(P.number, () => '2')
  .exhaustive(); // βœ…

And when the pattern and the input are literal types:

match<1 | 2>(1)
  .with(P.not(2), () => '1')
  .with(2, () => '2')
  .exhaustive(); // βœ