The void data type in Typescript represents the return value of functions which don’t return a value or return statement does not return anything.
Table of Contents
Void Data Type
The following example someFunc1
does not have return statement. someFunc2
does have a return statement but does not return anything. In such cases the Typescript infers the type as void
.
1 2 3 4 | function someFunc1() { //Inferred return is Void } |
1 2 3 4 5 6 | function someFunc2() { //Inferred return is Void return } |
You can also annotate the return type explicitly to void.
1 2 3 4 | function someFunc(): void { } |
Assigning to void
Nothing is assignable to void
except void
, undefined
& null
. You can assign null
to void
only if strictNullChecks
is set to false
in tsconfig.json
1 2 3 4 | let a:void a=undefined //No Error |
You cannot assign any other value to it. It will throw Type is not assignable to type ‘void’ error.
1 2 3 4 | a:void a="test" //Type 'string' is not assignable to type 'void'. |
But you cannot assign void
to undefined
1 2 3 4 5 6 7 8 | let a:undefined; let b:void; b=a; //ok a=b; //Type 'void' is not assignable to type 'undefined' |
Functions in JavaScript return undefined
if they do not return any values.
1 2 3 4 5 6 7 | function someFunc() { } let a = someFunc() console.log(a) //undefined |
To assign null first make the strictNullChecks
false in tsconfig.ts
. Remember that making to false is not a recommended practise.
1 2 3 4 5 6 7 | { "compilerOptions": { "strictNullChecks": false }, } |
1 2 3 4 | let a:void a=null //ok |
Void as function parameter
You can use void as the function parameter. The only valid values that you can pass is void
, undefined
& null
(strictNullChecks
is set to false
in tsconfig.json
)
1 2 3 4 5 6 7 8 9 10 11 12 | function someFunc(x:void) { } someFunc() //ok someFunc(undefined) //ok someFunc(null) //ok if strictNullChecks=false |
The underlying JavaScript neither has a data type void nor value.
Void data type can hold only one value i.e. undefined
(or null
if the strictNullChecks
compiler option is off). That is because JavaScript returns value undefined when the function does not return any value.
Why use void
When you that the function does not return any value, then it is better to annotate it with void
. This will prevent you from accidently returning a value.
1 2 3 4 5 | function voidFunction():void { return 10; //Type 'number' is not assignable to type 'void' } |
It also prevents you from storing and doing something with the return value.
1 2 3 4 5 6 7 8 9 | function voidFunction(): void { } let v = voidFunction(); v.boo; // Property 'boo' does not exist on type 'void' v + 20; // Operator '+' cannot be applied to types 'void' and 'number |
Similarities with Undefined
But you can also use undefined
instead of void
with the same effect.
1 2 3 4 5 | function voidFunction():undefined { return 10; //Type 'number' is not assignable to type 'undefined' } |
1 2 3 4 5 6 7 8 9 10 | function voidFunction():undefined { return undefined; } let v = voidFunction(); v.boo; // Property 'boo' does not exist on type 'void' v + 20; // Operator '+' cannot be applied to types 'void' and 'number |
void vs undefined
The above examples makes it appear that void is almost similar to undefined. But they have one difference.
If a function type specifies return type void
when implemented, can return any other value, but it will be ignored. The behavior is useful for advanced callback patterns
For Example, let us create a function type voidFunc
, whose return type is void
.
1 2 3 | type voidFunc = () => void; |
Now let us create three function of type voidFunc
. f1
which returns number, f2
which returns a boolean and f3
which returns a string. Although the voidFunc returns void, the Typescript compiler does not enforce f1, f3 & f3 function to return void, but instead ignores them. But it still infers the return type of these functions as void.
i.e. although v1
has value 10
compiler treats it as of type void
and hence does not allow us to use it any operations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | type voidFunc = () => void; const f1: voidFunc = () => { return 10; }; const f2: voidFunc = () => true; const f3: voidFunc = function () { return "Hello"; }; //v1, v2 & v3 are of type void const v1 = f1(); const v2 = f2(); const v3 = f3(); console.log(v1) //10 console.log(v2) //true console.log(v3) //hello //Since v1,v2 & v3 are voids you cannot use them v1+10; //not ok //Operator '+' cannot be applied to types 'void' and 'number' (v1 as number)+10 //not ok //Conversion of type 'void' to type 'number' may be a mistake //because neither type sufficiently overlaps with the other. //If this was intentional, convert the expression to 'unknown' first. |
Change the type to undefined and the compiler complaints. Since the voidFunc
returns undefined
, Typescript compiler also expects function f1
also return undefined
.
1 2 3 4 5 6 7 8 9 10 11 | type voidFunc = () => undefined; const f1: voidFunc = () => { return 10; }; //Type '() => number' is not assignable to type 'voidFunc'. //Type 'number' is not assignable to type 'undefined' |
The code above also works with the any
, but it defeats the purpose using TypeScript.
1 2 3 | type voidFunc = () => any; |
You can also use unknown type.
1 2 3 | type voidFunc = () => unknown; |
void is pretty useful in callback functions where callback function might return some value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function doSomeNumberCrunching(): number { return 42; } function doSomeStringCrunching(): string { return "Hello"; } function callMe(callback: () => void) { callback(); } let b = callMe(doSomeNumberCrunching); let c = callMe(doSomeStringCrunching); |