函数参数强制 <T | null | undefined> 类型

Force <T | null | undefined> type for function parameter

我们目前正在对较旧的代码库执行严格的 null 检查并自行构建助手

type Maybe<T> = T | null | undefined

我们实现了几个辅助函数,它们可能如下所示:

function isSafe<T>(val: Maybe<T>): val is T {
    // ...
}

Playground link

工作起来很有魅力,但我想要的改进是,防止非可能值作为参数传递,因为使用这种类型,可以调用 isSafe('hi'),它不能是 null,每个未包含在 Maybe.

中的变量都是这种情况

防止这样的调用会消除误解,因为我希望传递给 isSafe 的变量是 Maybe.

遗憾的是我还没有找到实现此目的的方法,因为 T | null | undefined 允许这些类型中的任何一种,而不仅仅是这 3 种类型的组合。

在将非 Maybe 值传递给函数时,有没有办法实现类型错误? 如果它也允许 T | nullT | undefined,那么奖励积分将是因为我们在内部决定我们将以相同的方式处理这两个值。

这是一个有点难看但符合您标准的解决方案:

type DefinitelyMaybe<T> = null extends T ? T : undefined extends T ? T : never

function isSafe<T>(val: DefinitelyMaybe<T>): val is NonNullable<typeof val> {
  return val !== null && val !== undefined;
}

// Argument of type 'string' is not assignable to parameter of type 'never'.
isSafe('test');

// OK
isSafe('test' as string | undefined);

本质上,DefinitelyMaybe<T>T 相同,只要 nullundefined 或两者都可分配给 T。否则,它是 never,导致调用站点出现类型错误,因为参数不可分配给它。

Playground Link