TypeScript 如何处理可能为空的变量
问题描述
如果我在使用(严格空值检查)TypeScript,并且我有一些可能为空的变量的代码:
let x = null;
if (someCondition) {
x = { a: 1 };
}
doSomethingWith(x.a);
我得到了一个错误,正如预期:
‘x’ 可能为 ‘null’。
我可以通过一个空值检查来修复这个错误:null
。
if (!x) return;
doSomethingWith(x.a);
但是我得到了:
类型“never”上不存在属性“a”。
真正的情况是,我希望写的是一个assert
调用,而不是一个if
/ return
:
const assert = value => { if (!value) throw Error(); }
assert(x);
doSomethingWith(x.a);
…但这甚至不能消除第一个错误。
我想出了一个解决方法,可以修复第二个错误:
(rootGroup as {id: number}).id
但我不确定这是否是最简单的解决方案,而且它还没有解决使用assert
函数的问题。
我的问题是,我怎么能够…?
- 创建一个”可能为空”的变量
- 运行一个能够证明它不为空的函数(如果为空则抛出错误)
- 添加(尽可能少的)TypeScript代码,然后
- 使用该变量,没有任何TypeScript错误
解决方案
你可以像这样使用断言签名:
let x: { a: 1 } | null = null
if (someCondition) {
x = { a: 1 }
}
// @ts-expect-error x maybe null
console.log(x.a)
assert(x) // asserting that x is truthy
console.log(x.a) // no error here
function assert(value: unknown): asserts value {
if (!value) {
throw new Error('foo')
}
}
如果你只想过滤掉nullish值,可以使用类似下面的方法:
function assertNotNull<T>(value: T): asserts value is NonNullable<T> {
if (value == null) {
throw new Error('bar')
}
}