Wrong type with when guard and generics
Author: zoontekCreated Dec 14, 2021Updated May 16, 2025
Hi
As I try to create compatibility between this library and ts-belt, I noticed an issue with when guards when they use generics.
import { match, when } from "ts-pattern";
type Nullish = null | undefined;
const someGuard = <T>(option: T | Nullish): option is T => option != null;
const noneGuard = <T>(option: T | Nullish): option is Nullish => option == null;
const __Some = when(someGuard);
const __None = when(noneGuard);
const array = Array<string>(Math.floor(Math.random() * 10)).fill("foo");
const item = array[5];
if (someGuard(item)) {
console.log(item); // type of item is string
}
if (noneGuard(item)) {
console.log(item); // type of item is undefined
}
match(item)
.with(__Some, item => { /* type of item is string | undefined, since ts-pattern struggles with generic type guards */ })
.with(__None, item => { /* type of item is undefined */ })
.exhaustive();It works without generic:
import { match, when } from "ts-pattern";
type Nullish = null | undefined;
const someStringGuard = (option: string | Nullish): option is string => option != null;
const noneStringGuard = (option: string | Nullish): option is Nullish => option == null;
const __Some = when(someStringGuard);
const __None = when(noneStringGuard);
const array = Array<string>(Math.floor(Math.random() * 10)).fill("foo");
const item = array[5];
if (someGuard(item)) {
console.log(item); // type of item is string
}
if (noneGuard(item)) {
console.log(item); // type of item is undefined
}
match(item)
.with(__Some, item => { /* type of item is string */})
.with(__None, item => { /* type of item is undefined */ })
.exhaustive();Is there a way to achieve this (a generic guard pattern)?
Source: gvergnaud/ts-pattern