首页 > 解决方案 > 自定义未定义检查的打字稿推断

问题描述

我无法想象这个问题还没有被问过,但我找不到。这可能与不知道要搜索哪些关键字来描述我的问题有关。

无论如何,假设我们有这个打字稿:

const value = undefined
const doSomethingWithValue = (value: number) => console.log(value)
const isDefined = (value?: unknown) => value != null

if (value != null) {
  doSomethingWithValue(value) // Works great!
}

if (isDefined(value)) {
  doSomethingWithValue(value) // Boo, error!: Argument of type 'undefined' is not assignable to parameter of type 'number'.
}

如您所见,该isDefined函数检查null/ undefined,但 Typescript 似乎无法像在if语句中使用显式检查时那样弄清楚它。我知道我可以像这样添加类型提示:

if (isDefined(value)) {
  doSomethingWithValue(value as unknown as number) // Works, but "eh"
}

这没关系,我想 - 绝对不理想。没有更好的方法吗?

编辑:非空断言运算符

所以,我刚刚了解到我可以像这样使用“非空断言运算符”,但它仍然不是“好”:

if (isDefined(value)) {
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  doSomethingWithValue(value!) // Works, not ideal still...
}

这可行,但需要禁用 eslint 规则@typescript-eslint/no-non-null-assertionhttps://github.com/typescript-eslint/typescript-eslint/blob/v5.1.0/packages/eslint-plugin/docs/rules/no-non-null-assertion。 md,文档警告:“使用非空断言取消了严格的空检查模式的好处。” 和“如果你不关心严格的空值检查,那么你就不需要这条规则。”

但是,我确实关心严格的空值检查!我不想完全禁用它

标签: typescript

解决方案


首先:


if (value != null) {
  doSomethingWithValue(value) // Works great!
}

它效果不佳。value被推断为never并可never分配给任何类型。

如果你想使用valueand isDefined,你应该转换isDefined自定义类型保护

declare const value: undefined | null | number;

const doSomethingWithValue = (value: number) => console.log(value)

const isDefined = <T,>(value: T | null | undefined):
  value is NonNullable<T> =>
  value != null && value !== undefined


if (isDefined(value)) {
  doSomethingWithValue(value) // ok
}

declare const value2: undefined | null | string;

if (isDefined(value2)) {
  value2 // string
}

操场


推荐阅读