我无法想象这个问题没有被问过,但是我找不到它。这可能与我不知道搜索什么关键词来描述我的问题有关。
无论如何,假设我们有这个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
可赋值给任何类型。
如果您想使用value
和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
}
游乐场