如何让TypeScript函数复用另一个函数的可空字段检查?
问题原因
TypeScript的类型窄化依赖当前作用域的静态代码分析,它无法自动关联外部函数的返回值与变量的类型状态:
isDataAvailable的签名仅返回boolean,没有向编译器传递“返回true时,data一定是非undefined”的类型信息;- 由于
data是let声明的可变变量,编译器会担心在调用isDataAvailable和访问data.i的间隙,data可能被其他代码修改为undefined。
解决方案
方案1:在当前作用域直接检查(最简单)
把检查逻辑内联到updateData中,让编译器直接在当前作用域完成类型窄化:
let data: { i: number; j: number } | undefined = undefined; const updateData = () => { if (data) { // 直接在当前作用域检查 data.i++; // 编译器确认data非undefined,无报错 } };
方案2:使用类型谓词(Type Predicate)
给isDataAvailable添加类型谓词,明确告知编译器函数返回值与data类型的关联:
let data: { i: number; j: number } | undefined = undefined; // 类型谓词:返回true时,data必然是{ i: number; j: number }类型 const isDataAvailable = (): data is { i: number; j: number } => { return !!data; }; const updateData = () => { if (isDataAvailable()) { data.i++; // 编译器识别类型断言,无报错 } };
如果希望函数更通用(不依赖全局变量),可以将data作为参数传入:
let data: { i: number; j: number } | undefined = undefined; const isDataAvailable = (d: typeof data): d is { i: number; j: number } => { return !!d; }; const updateData = () => { if (isDataAvailable(data)) { data.i++; // 同样能完成类型窄化 } };
方案3:将data改为不可变声明(如果业务允许)
如果data初始化后不需要被重新赋值为undefined,可以用const声明:
const data: { i: number; j: number } | undefined = undefined; const isDataAvailable = () => { return !!data; }; const updateData = () => { if (isDataAvailable()) { data.i++; // const声明的变量不可被重新赋值,编译器能确定类型状态 } };
内容的提问来源于stack exchange,提问作者Joey Yi Zhao
相关产品推荐
相关产品推荐

