Home > front end >  Does typescript have syntactic sugar around returning a value or throwing an exception if that value
Does typescript have syntactic sugar around returning a value or throwing an exception if that value

Time:12-19

I find myself wanting to do something like this a lot (pseudocode):

const something = somethingElse || throw an error

This would throw an error if somethingElse were falsy. Here's another example, written in real typescript:

const accessToken = process.env.ACCESS_TOKEN ?? throw new Error("The environment variable ACCESS_TOKEN was undefined or null");

This doesn't compile because the right-hand side needs to be an expression. Is there a way to write code functionally equivalent to the above while being comparable in terseness?

I can do the following, but I find it obnoxious to type and it uses up a lot of vertical space:

  const accessToken = process.env.PATREON_CREATORS_ACCESS_TOKEN;
  if (accessToken === undefined) {
    throw new Error("The environment variable PATREON_CREATORS_ACCESS_TOKEN was undefined");
  }

I could also create some utility function where you pass in something potentially falsy, and if it is falsy, throw an error. But I'm wondering if typescript/javascript provides some clever syntax to pull this off so I don't have to create such a function.

CodePudding user response:

Maybe I'm misunderstanding your criteria, but it seems easy enough to do with a function:

TS Playground

// https://developer.mozilla.org/en-US/docs/Glossary/Falsy
type Falsy = false | 0 | -0 | 0n | '' | null | undefined;

function truthy <T>(expr: T, msg = ''): Exclude<T, Falsy> {
  if (!expr) throw new Error(msg);
  return expr as Exclude<T, Falsy>;
}

declare const process: { env: Record<string, string | undefined> };

const accessToken = truthy(process.env.ACCESS_TOKEN, 'The environment variable ACCESS_TOKEN was undefined or null');

CodePudding user response:

This doesn't currently exist in TypeScript. Generally speaking, TypeScript doesn't adopt features that produce JavaScript output from non-JavaScript syntax. (Well, it doesn't do this anymore. Some older features like enums and parameter properties definitely behave this way. But if these features didn't already exist, they would be declined if you suggested them today.) If you file a new feature request you are supposed to check a box confirming that the suggestion "isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)". From now on, if we want to see new runtime features in TypeScript, they should be proposed to TC39, and TypeScript will implement it once the proposal reaches Stage 3 of the TC39 process.

There is an existing proposal for "throw expressions" which has been sitting at Stage 2 since sometime in 2017, so it doesn't look promising. There is also a TypeScript GitHub issue at microsoft/TypeScript#18535 and is stuck with status "Waiting for TC39". I guess we won't see this anytime soon.


In the throw expressions proposal, there is a workaround that implements something like a throwable expression:

const __throw = (err: any) => { throw err; };

Which you can see in action with your example:

process.env.ACCESS_TOKEN = (Math.random() < 0.5) ? "a token" : undefined;

const accessToken = process.env.ACCESS_TOKEN ??
    __throw(new Error("The environment variable ACCESS_TOKEN was undefined or null"));    
// maybe            
  • Related