我有一些代码,其中有几个函数需要对对象进行空检查,然后对其进行处理,或者如果它为空则抛出错误,如下所示:
interface SomeObject {
doThingOne: () => string;
doThingTwo: () => string;
}
let object: SomeObject | null;
function doThingOne() {
if(!object) {
throw new Error('Object is null!');
}
// Typescript knows that object is not null, so it's fine with accessing its properties/methods
return object.doThingOne();
}
function doThingTwo() {
if(!object) {
throw new Error('Object is null!');
}
return object.doThingTwo();
}
我想将 null 检查提取到函数中以减少重复代码,如下所示:
interface SomeObject {
doThingOne: () => string;
doThingTwo: () => string;
}
let object: SomeObject | null;
function requireObject() {
if(!object) {
throw new Error('Object is null!');
}
}
function doThingOne() {
requireObject();
// Typescript no longer knows that object is defined, so it gets mad at the next line
return object.doThingOne();
}
function doThingTwo() {
requireObject();
return object.doThingTwo();
}
但是,当我这样做时,typescript 不再知道在检查之后,object
确实存在。有没有一种干净的方法可以做到这一点?
This question看起来很相似,但实际上不会让我节省很多代码重复,因为我仍然需要设置 if
最佳答案
无法编写 requireObject()
并影响 object
的类型,因为编译器看不到 requireObject()
以任何方式与 object
相关。 (如果编译器能够管理由于函数内部封闭变量的突变而导致的所有可能的状态变化,那就太好了,但这在计算上不可行。请参阅 microsoft/TypeScript#9998 了解一般问题。)
您可以做的是将object
传递给requireObject()
并注释requireObject()
是一个assertion function。 .断言函数必须实现为 void
-returning(因此它们不返回任何内容),并且带注释的返回类型是 asserts x is Y
形式的“断言谓词” >(其中 x
是其中一个函数参数的名称)或者如果您想说 x
是 truthy,则只需 asserts x
.
所以这给了我们:
function requireObject(x: any): asserts x {
if (!x) {
throw new Error('something is falsy here');
}
}
现在我们可以毫无错误地做到这一点:
let object: SomeObject | null;
function doThingOne() {
requireObject(object);
return object.doThingOne(); // okay
}
function doThingTwo() {
requireObject(object);
return object.doThingTwo(); // okay
}
关于typescript - 如何将空检查拉入 typescript 中的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70365015/