4
Today I was asked what the guy is for never
Typescript, but it got confused for me. It just serves to say that it does not return anything? What’s the difference to the void
?
4
Today I was asked what the guy is for never
Typescript, but it got confused for me. It just serves to say that it does not return anything? What’s the difference to the void
?
3
never
The guy never
indicates that the function never returns something. That is, functions that generate an error or generate a loop have their return defined as never
. Quoting the documentation, in free translation:
The guy
never
represents the type of values that never occur. By example,never
is the type of return to a function or to a Arrow Function that always casts an exception or one that never returns; variables also acquire the typenever
when narrowed by any kind of protection that can never be true.The guy
never
is a subtype of and may be assigned to all types; in however, no type is a subtype of, or can be attributed to,never
(except the verynever
). Evenany
is not attributable tonever
.// Uma função retornando "never" deve ter um ponto final inacessível function error(message: string): never { throw new Error(message); } // O tipo de retorno inferido é "never" function fail() { return error("Aconteceu um erro!"); } // Uma função retornando "never" deve ter um ponto final inacessível function infiniteLoop(): never { while (true) { } }
A difference between the void
and the never
is that the guy void
can receive the value undefined
, as the guy never
cannot receive any value (only itself, never
).
I left the example below in Codesandbox so that it is possible to view the results and errors of lint.
function funcaoVoid(): void {
console.log("Executando funcaoVoid");
}
function funcaoNeverLoop(): never {
// Essa função gera um erro de loop infinito
console.log("Executando funcaoNeverLoop");
while (true) {}
}
function funcaoNeverErro(): never {
console.log("Executando funcaoNeverErro");
throw new Error("Erro gerado");
}
// Void
console.log('Chamada "funcaoVoid()":', funcaoVoid());
// Never - Loop
try {
console.log('Chamada "funcaoNeverLoop()":', funcaoNeverLoop());
} catch {
console.log('A função "funcaoNeverLoop()" foi chamada e entrou no "catch"');
}
// Never - Error
try {
console.log('Chamada "funcaoNeverErro()":', funcaoNeverErro());
} catch {
console.log('A função "funcaoNeverErro()" foi chamada e entrou no "catch"');
}
// Veja o erro em attr
const attr: never = undefined;
const attr2: void = undefined;
// O console.log() funciona para attr pois a tipagem em TS é apenas em tempo de compilação.
console.log(attr, attr2);
The results in the console are:
Executando funcaoVoid Chamada "funcaoVoid()": undefined Executando funcaoNeverLoop A função "funcaoNeverLoop()" foi chamada e entrou no "catch" Executando funcaoNeverErro A função "funcaoNeverErro()" foi chamada e entrou no "catch" undefined undefined
2
As stated in documentation:
The guy
never
is a subtype and attributable to any other type. However, no type is subtype or attributable to it (except itselfnever
). Up untilany
is not attributable tonever
.
It is basically a type that cannot happen. Its non-existence is a fact.
I am not going to go too far with the definition, as the documentation itself and the other answers here already provide this kind of information.
It is not valid to compare void
with never
, since it represents a value that exists (usually undefined
) and it does not exist, so it does not represent any possible value. Note that void
represents the absence of type (is the opposite of any
), while never
is the impossibility of having a value - applicable only for the type never
.
It is rare to find any use case for never
, but there are situations where it is especially useful. Generally, for narrow a set, as a union types. For example, we can create a type that removes number
s and string
s:
type NonNumberString<T> = T extends string | number ? never : T;
type All = undefined | null | string | number | boolean | symbol;
// %inferred-type: boolean | symbol | null | undefined
type Filtered = NonNumberString<All>;
Basically, the guy NonNumberString
uses a conditional type to check whether T
is attributable to number
or string
. If yes, never
will be returned. Otherwise, T
will be returned. This removes, ie fine tune our type by deleting string
or number
.
In this specific case, the built-in type Exclude
(see example here) comes to the same result. The intention here is to exemplify a case of use of narrowing types using the never
.
Another interesting use case is to ensure, through the code flow analysis of Typescript, that a variable has the type never
, that is, it cannot have value. This video explains this in more detail.
Browser other questions tagged typescript characteristic-language typing
You are not signed in. Login or sign up in order to post.
I can’t see a use and I’ve never even seen code using
never
, but it seems that it would be used only in function that would treat a message and then issue an error. Would it have any use with this type? First time I heard of him and I thought it was kind of weird, because I thoughtvoid
was enough. Or maybe the Intellisense show that the function is of the typenever
to draw the developer’s attention to some error that generates infinite loop... I do not know.– Cmte Cardeal
From the research I did on the Internet, for functions I only found these two examples, being that of generating error the most useful case (a function that generates a standard error for you). I think the best thing to gain from it is to call it that and you notice that it’s like
never
and already be able to understand in time what can happen, otherwise I did not find other points that caught my attention– Rafael Tavares
Thank you so much for the @Rafaeltavares reply, I am deleting the old answer to avoid interpretation problems
– David Schrammel