Reputation: 222503
bar
is expected to be a function with no return value:
let foo = () => 'foo';
let bar: () => void = foo; // produces no error
Can bar
be prevented from being assigned with a function that doesn't match expected () => void
signature?
For example, in this case:
declare let jsApiThatShouldNeverAcceptTypeofFoo = (bar: () => void) => void;
jsApiThatShouldNeverAcceptTypeofFoo(bar);
Upvotes: 2
Views: 90
Reputation: 249666
A partial workaround is to ensure that the return type of the function has no keys. This is satisfied by void
, but also by {}
and never
. This might be close enough, as functions retuning never
should throw an error and functions returning {}
happen infrequently enough:
type EnsureVoid<T> = keyof T extends never ?
void
: "Should not have a return type, only ()=> void is allowed";
declare let jsApiThatShouldNeverAcceptTypeofFoo: <T extends EnsureVoid<T>>(bar: ()=> T) => void;
let foo = () => 'foo';
jsApiThatShouldNeverAcceptTypeofFoo(foo) // Error
let bar = () => { };
jsApiThatShouldNeverAcceptTypeofFoo(bar)
let baz = () => ({ });
jsApiThatShouldNeverAcceptTypeofFoo(baz)
let boo = () => { throw "Error" };
jsApiThatShouldNeverAcceptTypeofFoo(boo)
Upvotes: 1
Reputation: 174967
No, because a void returning function is assignable to a value returning function. On the other hand, you can't use the return value if you expected a void returning function. i.e.
let foo = () => 'foo';
let bar: () => void = foo; // produces no error
const result = bar(); // foo in runtime, TypeScript thinks it's void
const upper = result.toUpperCase(); // compile error
Upvotes: 1