ITADN
gvergnaud/ts-pattern

版本发布 8

v5.9.0
? · 2025-10-26

## New features ### `P.record` patterns To match a `Record<Key, Value>` (an object with consistent key and value types), you can use `P.record(keyPattern, valuePattern)`. It takes a sub-pattern to match against the key, a sub-pattern to match against the value, and will match if **all entries** in the object match these two sub-patterns. ```ts import { match, P } from 'ts-pattern'; type Input = Record<string, number>; const input: Input = { alice: 100, bob: 85, charlie: 92, }; const output = match(input) .with(P.record(P.string, P.number), (scores) => `All user scores`) .with(P.record(P.string, P.string), (names) => `All user names`) .otherwise(() => ''); console.log(output); // => "All user scores" ``` You can also use `P.record` with a single argument `P.record(valuePattern)`, which assumes string keys: ```ts const userProfiles = { alice: { name: 'Alice', age: 25 }, bob: { name: 'Bob', age: 30 }, }; const output = match(userProfiles) .with( P.record({ name: P.string, age: P.number }), (profiles) => `User profiles with name and age` ) .otherwise(() => 'Different format'); console.log(output); // => "User profiles with name and age" ``` When using `P.select` in record patterns, you can extract all keys or all values as arrays: ```ts const data = { a: 1, b: 2, c: 3 }; const keys = match(data) .with(P.record(P.string.select(), P.number), (keys) => keys) .otherwise(() => []); const values = match(data) .with(P.record(P.string, P.number.select()), (values) => values) .otherwise(() => []); console.log(keys); // => ['a', 'b', 'c'] console.log(values); // => [1, 2, 3] ``` ## What's Changed * Fix: Add missing public/index.html to gif-fetcher example by @rio-sung-ks in https://github.com/gvergnaud/ts-pattern/pull/330 * set sideEffects to false to make ts-pattern tree shakable by @timvandam in https://github.com/gvergnaud/ts-pattern/pull/317 * feat(P.record): implementation by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/332 ## New Contributors * @rio-sung-ks made their first contribution in https://github.com/gvergnaud/ts-pattern/pull/330 * @timvandam made their first contribution in https://github.com/gvergnaud/ts-pattern/pull/317 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.8.0...v5.9.0

v5.7.1
? · 2025-05-18

## Type inference bug fixes This new release fixes the following bug in exhaustiveness checking when matching on optional properties: ```ts type Input = { type?: 'one' } | { type: 'two' }; const f1 = (input: Input) => match(input) .with({ type: 'one' }, () => {}) .with({ type: 'two' }, () => {}) .exhaustive(); // shouldn't type-check, but does 👎 const f2 = (input: Input) => match(input) .with({ type: 'one' }, () => {}) .with({ type: 'two' }, () => {}) .with({ type: undefined }, () => {}) // <- the type key needs to be present. .exhaustive(); // shouldn't type-check, but does 👎 ``` These two cases don't type check anymore. They fail with a `NonExhaustiveError<{ type?: undefined; }>`. To fix it, you should do: ```ts type Input = { type?: 'one' } | { type: 'two' }; const f = (input: Input) => match(input) .with({ type: 'one' }, () => {}) .with({ type: 'two' }, () => {}) .with({ type: P.optional(undefined) }, () => {}) // <- the type property may not be there .exhaustive(); // ✅ ``` This is a purely type-level change, the runtime behavior is still the same. ## What's Changed * fix(.exhaustive): optional discriminant by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/319 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.7.0...v5.7.1

v5.7.0
? · 2025-03-28
v5.6.2
? · 2025-01-21

## What's Changed * fix(isMatching): Fix non-object patterns by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/307 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.6.1...v5.6.2

v5.6.1
? · 2025-01-19

## What's Changed * fix(isMatching): Allow unknown properties in pattern by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/305 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.6.0...v5.6.1

v5.6.0
? · 2024-12-15

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: ```ts 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: ```ts 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: ```ts 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` and `isMatching` by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/302 * build(deps-dev): bump rollup from 2.79.1 to 2.79.2 by @dependabot in https://github.com/gvergnaud/ts-pattern/pull/289 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.5.0...v5.6.0

v5.5.0
? · 2024-10-14

## What's Changed * Export Pattern types in package.json by @GGomez99 in https://github.com/gvergnaud/ts-pattern/pull/292 ## New Contributors * @GGomez99 made their first contribution in https://github.com/gvergnaud/ts-pattern/pull/292 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.4.0...v5.5.0

v5.4.0
? · 2024-09-25

## The main thing — Faster type checking 🚀 This release brings a significant perf improvement to exhaustiveness checking, which lead 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 https://github.com/gvergnaud/ts-pattern/pull/273 * build(deps-dev): bump webpack from 5.91.0 to 5.94.0 in /examples/gif-fetcher by @dependabot in https://github.com/gvergnaud/ts-pattern/pull/276 * build(deps): bump serve-static and express in /examples/gif-fetcher by @dependabot in https://github.com/gvergnaud/ts-pattern/pull/283 * perf: improve type checking performance of BuildMany by @gvergnaud in https://github.com/gvergnaud/ts-pattern/pull/286 * Fixes type `InvertPatternForExcludeInternal` to work with readonly array by @changwoolab in https://github.com/gvergnaud/ts-pattern/pull/284 ## New Contributors * @changwoolab made their first contribution in https://github.com/gvergnaud/ts-pattern/pull/284 **Full Changelog**: https://github.com/gvergnaud/ts-pattern/compare/v5.3.1...v5.4.0