Search code examples
typescriptsyntaxnullnull-check

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


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.


Solution

  • 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.