Support for when predicate with .exhaustive()
when(predicate)
patterns and match(...).when(predicate)
are now permitted within .exhaustive()
match expressions.
If your predicate is a type guard function, the case will be considered handled:
type Input = 'a' | 'b'
match<Input>('a')
.exhaustive()
.when((x): x is 'a' => x === 'a' , () => {...})
.when((x): x is 'b' => x === 'b' , () => {...})
// This compiles
.run();
match<Input>('a')
.exhaustive()
.when((x): x is 'a' => x === 'a' , () => {...})
// This doesn't compiles
.run();
But if your predicate isn't a type guard, exhaustive checking will consider that this clause never matches anything:
match<Input>('a')
.exhaustive()
.when((x): x is 'a' => x === 'a' , () => {...})
.when(x => x === 'b' , () => {...})
// This doesn't compiles, because ts-pattern has no way to know that the 'b' case is handled
.run();
It works similarily with the when()
helper function:
type input = { type: 'success', data: string[] } | { type: 'error' }
match(input)
.exhaustive()
.with({ type: 'success', data: when(xs => xs.length > 0) }, () => {...})
.with({ type: 'error' }, () => {...})
// this doesn't compile, { type: 'success' } with an empty data array is not handled
.run();
match(input)
.exhaustive()
.with({ type: 'success', data: when(xs => xs.length > 0) }, () => {...})
.with({ type: 'success' }, () => {...})
.with({ type: 'error' }, () => {...})
// this compiles
.run();