The `never` Type: A Value That Should Never Exist
The `never` type represents a value that should never occur. It's used for functions that always throw an error or for exhaustive checks in switch statements to signal impossible states. The footgun is confusing it with `void`, which means 'returns nothing'.
WHY IT EXISTS: TypeScript needed a way to represent impossible states and unreachable code paths at the type level. This allows the compiler to perform more robust static analysis, like ensuring all cases in a discriminated union are handled, which makes code safer and more maintainable.
THE MENTAL MODEL: Think of never as the empty set of types. It represents a value that should never, ever occur. If a variable is typed as never, it means something has gone logically wrong in your type logic, because no value can be assigned to it.
HOW IT WORKS: never is a "bottom type." This means it is assignable to every other type, but no other type (except never itself) is assignable to it. A function can only have a never return type if it guarantees it will not have a reachable end point. This is typically achieved in two ways: by always throwing an exception or by entering an infinite loop.
WHEN TO USE IT: The primary use case is for exhaustive checking in switch statements or conditional logic. By assigning the final unhandled case to a never variable, you force the compiler to error if a new type is added to a union without being handled. It is also the correct return type for functions designed to always throw an error, clearly signaling their non-returning behavior to callers.
WHEN NOT TO USE IT: Do not use never when you mean void. A function that completes its execution but doesn't return a value (like console.log) has a return type of void. never is exclusively for functions or code paths that do not complete and never return control to the caller.
ONE CANONICAL EXAMPLE: Exhaustive checks with a discriminated union are the classic example. Consider a function handling different shapes: type Shape = "circle" | "square"; function getArea(s: Shape) { switch(s) { case "circle": return 1; case "square": return 2; default: const _exhaustiveCheck: never = s; return _exhaustiveCheck; } }. If you later add "triangle" to the Shape type, TypeScript will show an error on the _exhaustiveCheck line because the type "triangle" cannot be assigned to never, forcing you to handle the new case.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.