How to check for null value inline and throw an error in typescript?

Viewed 9340

In C# I can write code to check for null references and in case throw a custom exception, example:

var myValue = (someObject?.SomeProperty ?? throw new Exception("...")).SomeProperty;

In recent updates TypeScript introduced the null coalescing operator ?? but using it like the above statement produces a compilation error. Is there some similar allowed syntax in TypeScript?


To clarify, the desired behavior is achieved with the following code:

  if(someObject?.someProperty == null) {
    throw new Error("...");
  }

  var myValue = someObject.someProperty.someProperty;

The code:

  var myValue = someObject?.someProperty.someProperty;

works logically ok but throws a less meaningful exception.

3 Answers

As long as TypeScript doesn't support this natively, you could write a function similar to this one:

function throwExpression(errorMessage: string): never {
  throw new Error(errorMessage);
}

which would then allow you to throw an error as expression:

const myString = nullableVariable ?? throwExpression("nullableVariable is null or undefined")

The reason for the syntax error is that throw is a statement, so you can't use it as the operand to an operator.

There is a JavaScript proposal for throw expressions working its way through the TC39 process, currently at Stage 2. If it gets to Stage 3 you can expect it will show up in TypeScript soon thereafter. (Update at the end of 2020: However, it seems to have stalled, having been blocked in Jan 2018 by a TC39 member who didn't think they "...were sufficiently motivated if we have do expressions..." Note that do expressions are still StageĀ 1 here at the end of 2020, but at least they were presented to TC39 in June.)

With a throw expression, you could write this (if you want the value of someObject.someProperty):

const myValue = someObject?.someProperty ?? throw new Error("custom error here");

Or if you want someObject.someProperty.someProperty (which is what I think your C# version does):

const myValue = (someObject?.someProperty ?? throw new Error("custom error here")).someProperty;

There's a Babel plugin for it you can use now. Here's the first example above on Babel's REPL.


Side note: You've said you want to throw a custom error, but for anyone else reading this who doesn't need a custom error:

If you want someObject.someProperty.someProperty, with no error if someObject is null/undefined but getting an error if someObject.someProperty is null/undefined, you can do:

const myValue = someObject?.someProperty.someProperty;

With that:

  • If someObject is null or undefined, myValue will get the value undefined
  • If someObject is not null or undefined but someObject.someProperty is null or undefined, you'll get an error because we didn't use ?. after the first someProperty.
  • If someObject and someObject.someProperty are both not null or undefined, myValue will get the result of looking up someObject.someProperty.someProperty.

If you're interested in throwing the error within a single line, you could wrap it in an immediately invoked function expression:

const test = null ?? (() => {throw new Error("Test is nullish")})();

Related