I'm surprised why TypeScript 4.4.3 would not report an invalid type for the callback function?
This seems reasonable when returning a "non-promise" type but when returning a Promise it seems likely that we must wait for it to resolve.
setCallback
expects a function returning void
but is invoked with a function returning Promise<void>
indicates that there is something to wait for.
const setCallback = (cb: () => void): void => {
cb();
};
const callback = (): Promise<void> => {
return new Promise(resolve => {
setTimeout(() => resolve(), 100);
});
}
setCallback(callback);
CodePudding user response:
TypeScript doesn't care
You only give a function reference to setCallback()
which can be anything you like. As long as you don't invoke the function itself, it counts as an object
and TypeScript won't give you a TypeError since your function is expecting an object
.
If you were to call the object
, it would turn into it's respective type for which TypeScript does give you a TypeError in case of a mismatch.
- Variables passed by reference
In Pass by Reference, a function is called by directly passing the reference/address of the variable as the argument. Changing the argument inside the function affects the variable passed from outside the function. In Javascript objects and arrays are passed by reference.
- Functions (MDN)
Generally speaking, a function is a "subprogram" that can be called by code external (or internal in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function, and the function will return a value.
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
Example 1
Since I cannot use .then()
on void functions, I had to create an IIFE to make it async
and it still works even though I'm expecting a void type callback.
const setCallback = (cb: () => void): void => {
(async () => await cb())().then(() => console.log("Hi"));
};
const callback = (): Promise<number> => {
return new Promise(resolve => {
setTimeout(() => resolve(0), 100);
});
}
setCallback(callback);
Example 2
If you try to invoke it with a Promise
return type:
Argument of type 'Promise' is not assignable to parameter of type '() => void'. Type 'Promise' provides no match for the signature '(): void'.
The error refers to the mismatch of Function signatures.
const setCallback = (cb: () => void): void => {
(async () => await cb())().then(() => console.log("Hi"));
};
const callback = (): Promise<number> => {
return new Promise(resolve => {
setTimeout(() => resolve(0), 100);
});
}
setCallback(callback());