question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Infer non returning function to be returning `undefined`, not `void`

See original GitHub issue

Search Terms

non returning, undefined instead of void, undefined or unknown instead of void

Suggestion

  • Change return of non returning functions to undefined instead of void
  • Accept unknown as a type of non returning functions examples:
const f = () => {} // this gets inferred as () => void

const f1 = (): undefined => {} // doesn't work
// error: A function whose declared type is neither 'void' nor 'any' must return a value.(2355)

const f2 = (): unknown => {} // same error

https://www.typescriptlang.org/play/#code/MYewdgzgLgBAZjAvDAFASiQPhgbwL4CwAUMaJLHAIxKpoBcMArmACYCmcAlmGy1rjEIkiZaPABMNdA2YBrMCADuYfvmJA

Motivations

void is an annoying type to deal with, has many inconsistencies and there’s a ton of issues around it for its weird behavior like: #35850 , #35236 , #33420 … etc Non-returning functions actually return undefined which is a more predictable type to deal with and narrow disjunctions with and even use optional chaining with.

Use Cases

Many use cases appear while using promises where there’s a need to catch an error but at the same time not deal with void

const f = () => {}
async (p: Promise<A>) => {
  const a = await p.catch(f);
  // do stuff with a whose type is now A | void
};

Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code

Not sure if this might break some code or not but I think any code that dealt with void should work while dealing with undefined?

  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:12
  • Comments:14 (7 by maintainers)

github_iconTop GitHub Comments

7reactions
RyanCavanaughcommented, Jan 17, 2020

Let’s say today you write a function and there’s no useful value to return.

Then, next month, you decide that it’d be better if the function returned a number of some kind.

Is this a breaking change in your API contract?

If the non-returning version of the function was marked as void, then no, it can’t be a breaking change, because the rules around void effectively prevent a consumer from depending on the return value.

If the non-returning version of the function was marked as undefined, then yes, it absolutely can be a breaking change. Code like this

const p = fn() || 2;

would have been an error under void, but is OK under : undefined and now changes behavior. There is substantial risk of downstream code changing behavior when a function goes from returning “nothing” to returning “something”; having the “nothing” case be void mitigates that risk.

What are we getting in return? The “confusion” around void is generally around people not understanding what it means to mark a function’s return value as unspecified, which is its primary source of future-safety.

4reactions
sharnocommented, Jan 17, 2020

I disagree, for me, specified types/behavior trumps unspecified types/behavior. and I think that contradicts with your comments before that specified behavior should be annotated as so. Non-returning functions have a specified behavior too. https://github.com/microsoft/TypeScript/issues/35236#issuecomment-559280058

Oh, and that console.error and its friends should have their return types changed from void to undefined since that behavior is specified

Anyway, if you plan not to accept this issue, is it possible to accept an new issue to allow this?

function a(): undefined { }
function b(): unknown { }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does flowing off the end of a non-void function without ...
In C++ just flowing off the end of a value returning function is always undefined behavior (regardless of whether the function's result is...
Read more >
What Is Void in TypeScript? - Better Programming
A brief explanation to tell void apart from undefined or null ... All functions with no return value have an inferred return type...
Read more >
Void data type in TypeScript - TekTutorialsHub
The void data type in Typescript represents the return value of functions that don't return a value or return statements that do not...
Read more >
Documentation - Advanced Types - TypeScript
function f ( x : number, y ?: number) {. return x + ( y ?? 0);. } f (1, 2);. f (1);....
Read more >
Function.prototype.name - JavaScript - MDN Web Docs
It has no semantic significance to the language itself. ... where the name cannot be inferred is a function returned from another function:....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found