Reputation: 8949
I have read this, but it is unclear what would be the difference between 'never' and 'void' type?
Upvotes: 94
Views: 26167
Reputation: 337
void
represents the absence of a value for functions that do not return a value, while never
represents a value that never occurs for functions that throw errors or have infinite loops.
Upvotes: -1
Reputation: 44
Simply:
Void - function doesn't return anything or explicitly returns undefined.
Never - function never returns anything at all.
Upvotes: -1
Reputation: 282895
Here's another difference:
let x: string|never = undefined; // error: Type 'undefined' is not assignable to type 'string'.(2322)
let y: string|void = undefined; // ok
Upvotes: 3
Reputation: 3482
I will add examples. One function that returns nothing just prints to console. Function with side effect.
Correct definitions
function WriteToConsole():void{
console.log('console')
}
function WriteToConsole():any{
console.log('console')
}
Compile error
function WriteToConsole():never{
console.log('console')
}
function WriteToConsole():undefined{
console.log('console')
}
never type usually used when we have throw in the function
Upvotes: 2
Reputation: 728
The type never means that nothing occurs. It is used when a type guard cannot occur, or in a situation where an exception is always thrown. There is a difference between void and never. A function that has the explicit return type of never won’t allow returning undefined, which is different from a void function which allows returning undefined.
function functionThrow(): never {
throw new Error("This function return never");
}
For example, in the code below, there is an enum with two items. TypeScript knows that only two cases are possible and the default (else) case cannot occur. This insight of TypeScript is perfect since the function return type only accepts string, and does not accept never. If in the future you add a new item from enum, (for example, a ChoiceC without adding a new case in the switch statement), then the code can call the unhandledChoice function which returns never.
enum EnumWithChoices {
ChoiceA,
ChoiceB,
ChoiceC,
}
function functionReturnStringFromEnum(c: EnumWithChoices): string {
switch (c) {
case EnumWithChoices.ChoiceA:
return "A";
case EnumWithChoices.ChoiceB:
return "B";
default:
return unhandledChoiceFromEnum(c);
}
}
function unhandledChoiceFromEnum(x: never): never {
throw new Error("Choice not defined");
}
In the end, never indicates a state not meant to be. An exception is not expected behavior. An infinite loop in a function is not meant to be sustainable in a system, a condition that is never visited should not exist.
Upvotes: 7
Reputation: 4028
As Marius Schulz discusses in this article,
- A function that doesn't explicitly return a value implicitly returns the value
undefined
in JavaScript. Although we typically say that such a function "doesn't return anything", it returns. We usually ignore the return value in these cases. Such a function is inferred to have avoid
return type in TypeScript.- A function that has a
never
return type never returns. It doesn't returnundefined
, either. The function doesn't have a normal completion, which means it throws an error or never finishes running at all.
Upvotes: 67
Reputation: 5238
Never is information that this particular part shouldn't be reachable. For example in this code,
function do(): never {
while (true) {}
}
you have an infinite loop and we don't want to iterate infinite loop. Simply as that.
But a real question is how can it be useful for us? It might be helpful for instance while creating more advanced types to point what they are not
for example, let's declare our own NonNullable type:
type NonNullable<T> = T extends null | undefined ? never : T;
Here we are checking if T is null or undefined. If it is then we are pointing that it should never happen. Then while using this type:
let value: NonNullable<string>;
value = "Test";
value = null; // error
Void is information that functions with this type don't return any value, but they are reachable and they can be used.
Upvotes: 9
Reputation: 889
The return type of Promise.reject()
is Promise<never>
, meaning "it is never resolved".
So if a function returns Promise<never>
, I think it will return only errors. On the other hand, Promise<void>
might be resolved without value.
Upvotes: 6
Reputation: 188
Also, for more a theorical reason, with --strictNullChecks
new flag, TypeScript needed a new bottom type (since null
and undefined
are no more). The type never
is such a bottom type and make TypeScript's type system more consistent.
Upvotes: 11
Reputation: 221014
To augment Lee's very good answer, another way to think of it is that in a correctly-typed program, a never
value cannot be observed.
In addition to functions which never return (or which always throw exceptions), you'll see the never
type when a union type has been exhausted of all its possible constituents:
// Example assumes --strictNullChecks
function fn(x: number | string) {
if (typeof x === 'number') {
// x: number in this block
} else if (typeof x === 'string') {
// x: string in this block
} else {
// x: never in this block
// this block does not run; the value of x cannot be observed
}
}
Upvotes: 33
Reputation: 144136
In imperative languages, void
can be thought of as a type containing a single value. Such languages do not provide a means to construct or consume this value, but a void
function can be thought of as returning this trivial value.
In contrast never
is a type containing no values, which means that a function with this return type can never return normally at all. This means either throwing an exception or failing to terminate.
Upvotes: 48