自定义未定义检查的Typescript推断



我无法想象这个问题没有被问过,但是我找不到它。这可能与我不知道搜索什么关键词来描述我的问题有关。

无论如何,假设我们有这个Typescript:
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"
}

这是可以的,我想-绝对不是理想的。难道没有更好的办法吗?

EDIT:非空断言操作符

我刚刚学会了使用非空断言运算符就像这样,但它仍然不是"伟大";

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-assertion: https://github.com/typescript-eslint/typescript-eslint/blob/v5.1.0/packages/eslint-plugin/docs/rules/no-non-null-assertion.md,其中文档警告:"使用非空断言会取消严格的空检查模式的好处。"one_answers"如果你不关心严格的null检查,那么你就不需要这个规则。">

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

首先:


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

效果不太好。value被推断为never,never可赋值给任何类型。

如果您想使用valueisDefined,您应该将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
}

游乐场

相关内容

  • 没有找到相关文章

最新更新