Releases: gvergnaud/ts-pattern
v5.6.0
This release contains two changes:
Typecheck pattern when using isMatching with 2 parameter.
It used to be possible to pass a pattern than could never match to isMatching
. The new version checks that the provide pattern does match the value in second parameter:
type Pizza = { type: 'pizza'; topping: string };
type Sandwich = { type: 'sandwich'; condiments: string[] };
type Food = Pizza | Sandwich;
const fn = (food: Pizza | Sandwich) => {
if (isMatching({ type: 'oops' }, food)) {
// 👆 used to type-check, now doesn't!
}
}
Do not use P.infer
as an inference point
When using P.infer<Pattern>
to type a function argument, like in the following example:
const getWithDefault = <T extends P.Pattern>(
input: unknown,
pattern: T,
defaultValue: P.infer<T> // 👈
): P.infer<T> =>
isMatching(pattern, input) ? input : defaultValue
TypeScript could get confused and find type errors in the wrong spot:
const res = getWithDefault(null, { x: P.string }, 'oops')
// 👆 👆 type error should be here
// but it's here 😬
This new version fixes this problem.
What's Changed
- Improvements to
P.infer
andisMatching
by @gvergnaud in #302 - build(deps-dev): bump rollup from 2.79.1 to 2.79.2 by @dependabot in #289
Full Changelog: v5.5.0...v5.6.0
v5.5.0
v5.4.0
The main thing — Faster type checking 🚀
This release brings a significant perf improvement to exhaustiveness checking, which led to a ~16% decrease in the time to type-check the full test suite of TS-Pattern:
Category | Before | After | Evolution (%) |
---|---|---|---|
Instantiations | 6,735,991 | 4,562,378 | -32.33% |
Memory used | 732,233K | 746,454K | 1.95% |
Assignability cache size | 209,959 | 205,926 | -1.92% |
Identity cache size | 28,093 | 28,250 | 0.56% |
Check time | 5.78s | 4.83s | -16.44% |
What's Changed
- build(deps-dev): bump braces from 3.0.2 to 3.0.3 by @dependabot in #273
- build(deps-dev): bump webpack from 5.91.0 to 5.94.0 in /examples/gif-fetcher by @dependabot in #276
- build(deps): bump serve-static and express in /examples/gif-fetcher by @dependabot in #283
- perf: improve type checking performance of BuildMany by @gvergnaud in #286
- Fixes type
InvertPatternForExcludeInternal
to work with readonly array by @changwoolab in #284
New Contributors
- @changwoolab made their first contribution in #284
Full Changelog: v5.3.1...v5.4.0
v5.3.1
Pattern-matching on symbol keys
Symbols used to be ignored in object patterns. They are now taken into account:
const symbolA = Symbol('symbol-a');
const symbolB = Symbol('symbol-b');
const obj = { [symbolA]: { [symbolB]: 'foo' } };
if (isMatching({ [symbolA]: { [symbolB]: 'bar' } }, obj)) {
// 👆 Used to return true, now returns false!
// Since TS-Pattern wasn't reading symbols, this pattern used to be equivalent
// to the `{}` pattern that matches any value except null and undefined.
}
.exhaustive
now throws a custom error
People have expressed the need to differentiate runtime errors that .exhaustive()
might throw when the input is of an unexpected type from other runtime errors that could have happened in the same match expression. It's now possible with err instanceof NonExhaustiveError
:
import { match, P, NonExhaustiveError } from 'ts-pattern';
const fn = (input: string | number) => {
return match(input)
.with(P.string, () => "string!")
.with(P.number, () => "number!")
.exhaustive()
}
try {
fn(null as string) // 👈 💥
} catch (e) {
if (e instanceof NonExhaustiveError) {
// The input was invalid
} else {
// something else happened
}
}
What's Changed
- build(deps-dev): bump braces from 3.0.2 to 3.0.3 in /examples/gif-fetcher by @dependabot in #262
- feat: throw custom
ExhaustiveError
when no matched pattern by @adamhamlin in #270 - Symbols as keys by @Ayc0 in #272
New Contributors
- @adamhamlin made their first contribution in #270
- @Ayc0 made their first contribution in #272
Full Changelog: v5.2.0...v5.3.1
v5.2.0
The main thing
new P.string.length(n)
pattern
P.string.length(len)
matches strings with exactly len
characters.
const fn = (input: string) =>
match(input)
.with(P.string.length(2), () => '🎉')
.otherwise(() => '❌');
console.log(fn('ok')); // logs '🎉'
What's Changed
- docs: fix typo in
P.when
patterns code example by @grigorischristainas in #260 - feat: Added P.string.length by @JUSTIVE in #257
New Contributors
- @grigorischristainas made their first contribution in #260
Full Changelog: v5.1.2...v5.2.0
v5.1.2
The main thing
When combining P.nonNullable
and P.nullish
, you should get an exhaustive pattern matching expression, but the following case was incorrectly considered non-exhaustive:
declare const input: {
nested: string | number | null | undefined;
};
const res = match(input)
.with({ nested: P.nonNullable }, (x) => {/* ... */})
.with({ nested: P.nullish }, (x) => {/* ... */})
// should type-check
.exhaustive();
This is fixed now.
What's Changed
- build(deps): bump postcss and react-scripts in /examples/gif-fetcher by @dependabot in #243
- build(deps): bump loader-utils and react-scripts in /examples/gif-fetcher by @dependabot in #242
- build(deps): bump jsdom and react-scripts in /examples/gif-fetcher by @dependabot in #241
- build(deps): bump tough-cookie and react-scripts in /examples/gif-fetcher by @dependabot in #240
- build(deps): bump shell-quote and react-scripts in /examples/gif-fetcher by @dependabot in #239
- chore: add P.map specific jsdoc for P.map by @momentiris in #245
- build(deps-dev): bump ejs from 3.1.9 to 3.1.10 in /examples/gif-fetcher by @dependabot in #249
- build(deps-dev): bump ejs from 3.1.9 to 3.1.10 by @dependabot in #248
- fix: exhaustive checking with nested P.nonNullable patterns by @gvergnaud in #252
New Contributors
- @momentiris made their first contribution in #245
Full Changelog: v5.1.1...v5.1.2
v5.1.1
What's Changed
- Fix(P.nonNullable): narrowing of unions of objects by @gvergnaud in #237
Full Changelog: v5.1.0...v5.1.1
v5.1.0
New features
P.nonNullable
wildcard
Add a new P.nonNullable
pattern that will match any value except null
or undefined
.
import { match, P } from 'ts-pattern';
const input = null;
const output = match<number | null | undefined>(input)
.with(P.nonNullable, () => 'it is a number!')
.otherwise(() => 'it is either null or undefined!');
console.log(output);
// => 'it is either null or undefined!'
Closes #60 #154 #190 and will be a work-around for #143.
What's Changed
- feat: Add P.nonNullable patterns by @gvergnaud in #229
Full Changelog: v5.0.8...v5.1.0
v5.0.8
The main thing
This release includes type narrowing improvement to isMatching
when used in its curried form:
type Pizza = { type: 'pizza', topping: string };
type Sandwich = { type: 'sandwich', condiments: string[] }
type Food = Pizza | Sandwich;
declare const food: Food
const isPizza = isMatching({ type: 'pizza' })
if (isPizza(food)) {
x // Used to infer `food` as `Food`, no infers `Pizza`
}
This also improves type checking performance for complex patterns and fixes a small bug in the ES5 build of TS-Pattern.
What's Changed
- perf: support exhaustive match on larger unions by @gvergnaud in #214
- fix: make isMatching(p) infer the pattern as a const type parameter by @gvergnaud in #221
- fix: Make sure regeneratorRuntime isn't included in the cjs build by @gvergnaud in #224
Full Changelog: v5.0.6...v5.0.8
v5.0.6
Close issue issues
What's Changed
- Update README.md by @ndstephens in #161
- docs: add install instructions for bun and pnpm by @colinhacks in #186
- build(deps-dev): bump postcss from 8.4.23 to 8.4.31 by @dependabot in #199
- build(deps-dev): bump @babel/traverse from 7.21.5 to 7.23.2 by @dependabot in #200
- fix(readonly): exhaustive matching on readonly array by @gvergnaud in #207
New Contributors
- @ndstephens made their first contribution in #161
- @colinhacks made their first contribution in #186
Full Changelog: v5.0.5...v5.0.6