If you come from a traditional strongly typed language, you may be familiar with the concept of void: a type that tells you that functions and methods do not return anything when called.
void exists in JavaScript as an operator, and in TypeScript as a primitive type. In these two worlds, void works a little differently than most people are used to.
void in JavaScript
void in JavaScript is an operator that calculates the expression next to it. No matter which expression is evaluated, void always returns undefined.
let i = void 2; // i === undefined
Why do we need something like this? First in the early days, people were able to override undefined and give it an actual value. void always returns real undefined.
Second, this is a good way to call a function immediately:
void function() { ('What') }()
All of this does not pollute the global namespace:
void function aRecursion(i) { if(i > 0) { (i--) aRecursion(i) } }(3) (typeof aRecursion) // undefined
Since void always returns undefined, and void always calculates the expression next to it, you have a very concise way to return from the function without returning a value, but still call a callback for example:
// returning something else than undefined would crash the app function middleware(nextCallback) { if(conditionApplies()) { return void nextCallback(); } }
This reminds me of the most important path to void: it is the security door for your program. When your function should always return undefined , you can make sure that is always the case.
= () => void doSomething();
void in TypeScript
void in TypeScript is a subtype of undefined. Functions in JavaScript always return something. Either it is a value or it is undefined:
function iHaveNoReturnValue(i) { (i) } // returns undefined
Because functions without return values ββalways return undefined, and void always return undefined in JavaScript, void in TypeScript is a correct type, telling developers that this function returns undefined:
declare function iHaveNoReturnValue(i: number): void
void as a type can also be used for parameters and all other declarations. The only value that can be passed is undefined:
declare function iTakeNoParameters(x: void): void iTakeNoParameters() // π iTakeNoParameters(undefined) // π iTakeNoParameters(void 2) // π
So void and undefined are almost the same. Although it's a little different, this difference is huge: void as return type can be replaced with different types to allow for advanced callback modes:
function doSomething(callback: () => void) { let c = callback() // at this position, callback always returns undefined //c is also of type undefiend } // this function returns a number function aNumberCallback(): number { return 2; } // works π type safety is ensured in doSometing doSomething(aNumberCallback)
This is the expected behavior and is usually used in JavaScript programs. You can read more about this pattern called substitutability in my other posts.
If you want to make sure that you pass functions that only return undefined (such as "nothing"), make sure to adjust your callback method signature:
- function doSomething(callback: () => void) { + function doSomething(callback: () => undefined) { /* ... */ } function aNumberCallback(): number { return 2; } // π₯ types don't match doSomething(aNumberCallback)
You can get along well with void most of the time.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.