I mean it should return undefined or no return at all. Typical for safe callbacks.
Tryout 1:
declare const fn1: (cb: () => void) => void;
fn1(() => '123'); // no error
Oops. It didn't work out. string is applicable to void. Ok...
Tryout 2:
declare const fn2: (cb: () => unknown) => void;
fn2(() => '123'); // no error
Oops. The same. Ooookay.
Tryout 3:
declare const fn3: (cb: () => undefined) => void;
fn3(() => '123'); // error: Type 'string' is not assignable to type 'undefined'
Nice! Ok, go with it:
fn3(() => undefined); // okay
fn3(() => {}); // error: Type 'void' is not assignable to type 'undefined'
Hm. It's not what I'm looking for.
Okay, what's about this crazy idea? Tryout 4:
declare const fn4: (cb: () => void | undefined) => void;
fn4(() => undefined); // okay
fn4(() => { }); // okay
fn4(() => '123'); // error: Type 'string' is not assignable to type 'undefined'
Wow. It's what I wanted.
But it looks like a dirty hack. Why on the Earth void doesn't complain about string, but void | undefined does it? Is it a bug?
Can I rely on this behavior? Wouldn't it be fixed in some future versions of TS? Is there any better way to accomplish the same?