gvergnaud / ts-pattern

🎨 The exhaustive Pattern Matching library for TypeScript, with smart type inference.
MIT License
12.15k stars 129 forks source link

`Pattern.nonNullable` does not behave as expected #247

Closed ItaiYosephi closed 4 months ago

ItaiYosephi commented 6 months ago

Describe the bug Pattern.nonNullable behave the same Pattern.not(Pattern.nullish)

Code Sandbox with a minimal reproduction case https://codesandbox.io/p/sandbox/thirsty-frog-9965h3?file=%2Fsrc%2Findex.ts%3A20%2C14

provided this code

enum AnimalType {
  Dog = "dog",
  Cat = "cat",
}

interface Animal {
  type?: AnimalType;
  name: string;
}

const animal: Animal = { name: "Bobbie" };

match(animal)
  .with(
    // replace the next line with:
    // { type: Pattern.not(Pattern.nullish) },
    { type: Pattern.nonNullable },
    ({ name, type }) => `${name} the ${type}`
  )
  .with({ type: Pattern.optional(Pattern.nullish) }, ({ name }) => name)
  .exhaustive();

match(animal)
  .with(
    { type: Pattern.not(Pattern.nullish) },
    { type: Pattern.nonNullable },
    ({ name, type }) => `${name} the ${type}`
  )
  // without `Optional` - there's no TS error, but there is runtime error
  .with({ type: Pattern.nullish }, ({ name }) => name)
  .exhaustive();

I get this ts error CleanShot 2024-04-16 at 11 21 30@2x

Versions

gvergnaud commented 5 months ago

That's indeed a bug. I'll take a closer look when I get some time. In the meantime using P.not(P.nullish) instead of P.nonNullable is the alternative I'd recommend if you run into this issue

TS Playground for reference

gvergnaud commented 4 months ago

Fixed in 5.1.2!