What if your code could tell you when you're writing lines that will never run?
Why Never type and unreachable code in Typescript? - Purpose & Use Cases
Imagine you write a program and add extra lines of code that never run because the program stops before reaching them. You keep typing and fixing these lines, but they never do anything.
This wastes your time and can hide real problems. You might think your code works, but some parts are just dead weight. It's easy to miss bugs or misunderstand what your program really does.
The never type in TypeScript helps you catch these unreachable parts early. It tells you when some code can never run, so you can clean it up or fix your logic. This keeps your code clear and error-free.
function example(x: string | number) {
if (typeof x === 'string') {
console.log('String');
} else if (typeof x === 'number') {
console.log('Number');
} else {
console.log('Unknown'); // This is unreachable
}
}function example(x: string | number) {
if (typeof x === 'string') {
console.log('String');
} else if (typeof x === 'number') {
console.log('Number');
} else {
const _exhaustiveCheck: never = x;
return _exhaustiveCheck;
}
}You can write safer code that clearly shows when all cases are handled and no hidden errors lurk.
When building a menu with fixed options, never helps ensure you handle every choice. If a new option is added later, TypeScript warns you to update your code, preventing bugs.
Unreachable code wastes time and hides bugs.
never type catches unreachable or impossible cases.
This leads to clearer, safer, and easier-to-maintain code.
Practice
never type represent in TypeScript?Solution
Step 1: Understand the
Thenevertype meaningnevertype is used for functions or expressions that never complete normally, such as those that throw errors or run infinite loops.Step 2: Compare with other types
Other options describe common types like any, null, or optional, which are different fromnever.Final Answer:
A function that never returns normally, like one that always throws an error or loops forever. -> Option DQuick Check:
nevermeans no normal return [OK]
- Confusing never with void or any
- Thinking never means optional or nullable
- Assuming never is a value type
never in TypeScript?Solution
Step 1: Check function return type and body
A function returningnevermust not return normally. Throwing an error fits this.Step 2: Validate each option
function fail(): never { throw new Error('Fail'); } throws an error, so it never returns normally. function fail(): void { return; } returns void normally. function fail(): never { return null; } tries to return null, which is invalid for never. function fail(): string { throw new Error('Fail'); } returns string but throws, so return type mismatches.Final Answer:
function fail(): never { throw new Error('Fail'); } -> Option AQuick Check:
Throw error matches never return [OK]
- Returning a value in a never function
- Using void instead of never
- Returning null or undefined in never
function check(value: string | number) {
switch (typeof value) {
case 'string':
return 'string';
case 'number':
return 'number';
default:
const _exhaustiveCheck: never = value;
return _exhaustiveCheck;
}
}
console.log(check(42));Solution
Step 1: Analyze the switch cases
The function handles 'string' and 'number' types explicitly, so the default case is unreachable for these inputs.Step 2: Check the call and output
Callingcheck(42)matches the 'number' case, so it returns 'number'. The default case withneveris never reached.Final Answer:
'number' -> Option BQuick Check:
Handled all cases, returns 'number' [OK]
- Thinking default case runs for known types
- Confusing never with runtime errors
- Expecting compilation error for unreachable default
function assertNever(x: never): never {
throw new Error('Unexpected value: ' + x);
}
function process(value: string | number) {
if (typeof value === 'string') {
return 'string';
} else if (typeof value === 'number') {
return 'number';
} else {
return assertNever(value);
}
}Solution
Step 1: Understand the function purpose
assertNeveris used to catch unexpected values at compile time by requiring anevertype.Step 2: Analyze the
All possible typesprocessfunctionstringandnumberare handled. The else branch is unreachable, sovalueisneverthere, making the call valid.Final Answer:
No error; code is correct and safe. -> Option CQuick Check:
Unreachable else means value is never [OK]
- Thinking assertNever is called with string or number
- Confusing never return with void
- Assuming else branch always runs
type Shape = { kind: 'circle', radius: number } | { kind: 'square', size: number };
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
// Missing case for 'square'
}
}Solution
Step 1: Identify missing case problem
The 'square' case is missing, so the switch is not exhaustive.Step 2: Use never type to catch missing cases
Adding adefaultcase that calls a function requiringneverforces TypeScript to check exhaustiveness and report missing cases.Final Answer:
Add adefaultcase that calls a function acceptingneverto catch unhandled cases. -> Option AQuick Check:
Use never in default to enforce exhaustiveness [OK]
- Assuming TypeScript warns without default never
- Returning default values silently
- Using any to bypass type safety
Ready to prove it?
Pass the test and this pattern moves unknown
