启用strictNullChecks后,是否可以在不需要Non-Null断言运算符的情况下进行断言?

时间:2019-01-04 00:47:45

标签: typescript

tl; dr:我希望能够使用assert实用程序来检查值是否为非空,然后让Typescript理解该值是否为非空。我已启用strictNullChecks,并且我不想使用非null断言运算符。

根据the typescript docs,我可以使用断言的一种方法是使用非空断言运算符(从文档稍作修改):

// Compiled with --strictNullChecks
function assertEntity(e?: Entity) {
  // Throw exception if e is null or undefined
}

function processEntity(e?: Entity) {
  assertEntity(e);
  let s = e!.name;  // Assert that e is non-null and access name
}

但是,我更喜欢不经常使用断言,因为它们容易被滥用。我宁愿做这样的事情:

// Add a good return type to assertEntity to clarify that it may throw
function assertEntity(e?: Entity): void | never {
  if (!e) {
    throw Error('Entity is falsy!');
  }
}

function processEntity(e?: Entity) {
  assertEntity(e);

  // At this point I'd like typescript to know that e is truthy
  let s = e.name;
}

文档说,非空断言运算符将在“类型检查器无法得出该事实的地方”使用。我的问题是,有什么办法可以帮助类型检查器正确得出e不为空的结论?

我已经知道执行此操作的几种方法,这些方法比我想要的要多一些。例如,我可以使用user-defined type guard,但这可能导致缩进级别更高:

function checkEntity(e: any): e is Entity {
  return e && e.name;
}

function processEntity(e?: Entity) {
  assertEntity(e);

  // This checkEntity call seems superfluous, since I'm already
  // calling assertEntity above.
  if (checkEntity(e)) {
    let s = e.name;
  }
}

或者我可以用不同的方式来做到这一点,这也解决了类型问题,但是由于它具有虚假的早期返回,因此需要一些误导性代码:

// Note that assertEntity is now a user-defined type guard, because of
// the `e is Entity` return value.
function assertEntity(e?: Entity): e is Entity {
  if (!e) {
    throw Error('Entity is falsy!');
  }
  return true;
}

function processEntity(e?: Entity) {
  // I can make assertEntity into a user-defined type guard, but then this
  // code looks as if it might have an early return, when in fact it will throw
  // if `e` is falsy.
  if (!assertEntity(e)) {
    return; // This return is impossible to reach
  }
  let s = e.name;
}

0 个答案:

没有答案