Typescript: Allow non returning functions to have contextually required `undefined` return type

Created on 18 Jan 2020  ·  5Comments  ·  Source: microsoft/TypeScript

Search Terms

36239

Suggestion

Allow non returning functions to have contextually required undefined return type.

Use Cases

  • Callbacks

Examples

declare function f(a: () => undefined): void;
f(() => { }); // error -> ok
f((): undefined => { }); // error -> ok
const g1: () => undefined = () => { }; // error -> ok
const g2 = (): undefined => { }; // error -> ok if possible
function h1() {
}
f(h1); // error -> error
function h2(): undefined { // error -> ok if possible
}

Checklist

My suggestion meets these guidelines:

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

Most helpful comment

I like this idea 👍

All 5 comments

I like this idea 👍

This would be great.

I'm working with an API that's typed in closure compiler's ES4 type system as () => boolean|undefined and the TypeScript functions passed in are required to explicitly return undefined. If I omit the return, they're typed as void and generate the error Type 'void' is not assignable to type 'boolean | undefined'.(2322)

e.g.

type listener = () => boolean | undefined;
function listen(listener: listener) { }

listen(() => true);  // ok
listen(() => undefined); // ok
listen(() => { });  // error!

What needs to happen to allow the listener callback type to omit return statements? Any chance of this landing in a future release?

I have a lot of code that has functions with return types of undefined or T|undefined.

I'd be happy to try to take this on myself, if a project member could give some pointers as to how such a thing could be implemented.

The idea is that any argument accepting a function parameter whose return type includes undefined could accept a non-returning function instead of requiring an explicit return undefined. Explicitly returning undefined is pretty weird when that's the default behavior of a non-returning function in JavaScript.

Do note that an explicit return statement without any value causes TypeScript to allow the undefined return type annotation.

const ok = (): undefined => {
    return; // This explicit return statement is currently required
};

Consider ReactJS's useEffect, the first argument must be a function that returns void | (() => void | undefined).
The problem is the following is valid:

const f: () => void = () => 42;
useEffect(f);

IMO, an API which expects a function that returns void means it will not look at the return value, which isn't the case.
In a sense, void as a return value is more like unknown than undefined.

But if the API had been correctly defined as declare function useEffect(f: () => undefined | (() => void)): void;, the following wouldn't typecheck with noImplicitReturns:

useEffect(() => {});

I believe accepting this suggestion would help defining better APIs.

Was this page helpful?
0 / 5 - 0 ratings