typescript - 如何将空检查拉入 typescript 中的功能

标签 typescript types null

我有一些代码,其中有几个函数需要对对象进行空检查,然后对其进行处理,或者如果它为空则抛出错误,如下所示:

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 是其中一个函数参数的名称)或者如果您想说 xtruthy,则只需 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
}

Playground link to code

关于typescript - 如何将空检查拉入 typescript 中的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70365015/

相关文章:

list - 如何使用自定义版本的List : `data List a = Nil | Cons a (List a)` ?

haskell - 如果我们可以禁用功能,错误消息会改善吗?

sql - Kotlin可选,或类似的东西

php - "Bad"练习乘以$val * 1 将null 转换为零

javascript - 处理javascript空对象的简洁方法

typescript 类型字符串不可分配给类型 keyof

Typescript Mongoose 在 VS Code 中获取架构字段的 IntelliSense 或警告

java - 我可以在 Java 或 Scala 中定义这些类型吗?

json - 如何将 package.json 导入 Typescript 文件而不将其包含在编译输出中?

javascript - JavaScript Promise 中的可选 catch