You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow non returning functions to have contextually required undefined return type #36288
Reacted by falsandtru, Stepan Zubashev, Angel Gonzalez, William Furr, Kagami Sascha Rosylight, Steven, ExE Boss, Michał Dudak, Okku, GrishaevPavel and 11 more
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.
Consider ReactJS's useEffect, the first argument must be a function that returns void | (() => void | undefined).
The problem is the following is valid:
constf: ()=>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.
Reacted by Bergi, ExE Boss, Petra Jaros, Jan Peša and matthewvalentine
I'd like to vote against this -- or at least provide it as a tsconfig option (so that we're not forced to use it).
In fact, I would like to propose making returns more explicit than they are today. Currently the compile error goes away providing your method has at least one terminal branch with an explicit return... it would seem safer IMO if the error only goes away once all terminal branches have an explicit return:
I have many T | undefined in my code: if I forget to explicitly return a value from a terminal branch, there's only a 50% chance that the implicitly returned undefined is the correct value to return (meaning a 50% chance of a bug).
Consider bugs like this, which would be prevented if every terminal branch required a return:
functionfoo(): number|undefined{if(someFunction()){returnundefined}constvalue: number=someOtherFunction()anotherFunction(value)// return value <- The code I forgot to write! Today this compiles fine... but it shouldn't IMO.}
So tbh rather than making the returns more implicit, it would be safer to make them more explicit.
(falsandtru (@falsandtru)Ryan Cavanaugh (@RyanCavanaugh) sorry for the "thumbs downs": your comments are great, I just wanted the maintainers to see at a glance that someone has an issue with the proposed change, as currently it looks unanimously in favour 😄)
Activity
RyanCavanaugh commentedon Jan 23, 2020
I like this idea 👍
wffurr commentedon Jul 6, 2020
This would be great.
I'm working with an API that's typed in closure compiler's ES4 type system as
() => boolean|undefinedand the TypeScript functions passed in are required to explicitly returnundefined. If I omit the return, they're typed asvoidand generate the errorType 'void' is not assignable to type 'boolean | undefined'.(2322)e.g.
What needs to happen to allow the listener callback type to omit return statements? Any chance of this landing in a future release?
wffurr commentedon Jul 28, 2020
I have a lot of code that has functions with return types of
undefinedorT|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
undefinedcould accept a non-returning function instead of requiring an explicitreturn undefined. Explicitly returning undefined is pretty weird when that's the default behavior of a non-returning function in JavaScript.ExE-Boss commentedon Sep 6, 2020
Do note that an explicit return statement without any value causes TypeScript to allow the
undefinedreturn type annotation.ilogico commentedon Sep 8, 2020
Consider ReactJS's
useEffect, the first argument must be a function that returnsvoid | (() => void | undefined).The problem is the following is valid:
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
unknownthanundefined.But if the API had been correctly defined as
declare function useEffect(f: () => undefined | (() => void)): void;, the following wouldn't typecheck withnoImplicitReturns:I believe accepting this suggestion would help defining better APIs.
ljwagerfield commentedon May 26, 2021
I'd like to vote against this -- or at least provide it as a tsconfig option (so that we're not forced to use it).
In fact, I would like to propose making returns more explicit than they are today. Currently the compile error goes away providing your method has at least one terminal branch with an explicit return... it would seem safer IMO if the error only goes away once all terminal branches have an explicit return:
I have many
T | undefinedin my code: if I forget to explicitly return a value from a terminal branch, there's only a 50% chance that the implicitly returnedundefinedis the correct value to return (meaning a 50% chance of a bug).Consider bugs like this, which would be prevented if every terminal branch required a
return:So tbh rather than making the returns more implicit, it would be safer to make them more explicit.
(falsandtru (@falsandtru) Ryan Cavanaugh (@RyanCavanaugh) sorry for the "thumbs downs": your comments are great, I just wanted the maintainers to see at a glance that someone has an issue with the proposed change, as currently it looks unanimously in favour 😄)
RyanCavanaugh commentedon May 26, 2021
Lawrence Wagerfield (@ljwagerfield) it sounds like you should turn on the
noImplicitReturnsflag, which does exactly that?ljwagerfield commentedon May 27, 2021
Excellent, so it does!
In that case, assuming
noImplicitReturns: trueworks the same after the proposed changes, then I'm happy to withdraw my reservation.Thanks again Ryan Cavanaugh (@RyanCavanaugh) !
borgesius commentedon Feb 18, 2022
Very cool I like it this would have saved me two hours of bugfixing earlier 👍
bombillazo commentedon May 19, 2022
This would be a great feature to incorporate into TS!
akouryy commentedon Jun 16, 2022
It sounds great. In this example,
eandhare already typed whennoImplicitReturns: false.It would be more consistent to allow
fandiundernoImplicitReturns: false.This change seems to have no drawbacks. What blocks approval of it?
stevenwdv commentedon Oct 18, 2022
I'm all for this! This would allow typing event handlers as
(ev: Event) => undefined | booleaninstead of the weird(ev: Event) => any:DEdit: The current implementation still doesn't allow this as it blocks unions with
undefined:(DanielRosenwasser commentedon Mar 17, 2023
Thank you Kagami Sascha Rosylight (@saschanaz)!
lolbinarycat commentedon Mar 4, 2025