How to fix Cannot access member 'x' for a type which is 'never' in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 8, 2025· 116 views

This error occurs when TypeScript's type narrowing determines that a code path is unreachable (type 'never'), and you're attempting to access properties on it. The fix involves proper type guards and exhaustiveness checking.

Quick fix

Fixes Cannot access member 'x' for a type which is 'never'

type Status = 'pending' | 'success' | 'error';

function handleStatus(status: Status) {
  if (status === 'pending') {
    // handle pending
  } else if (status === 'success') {
    // handle success
  }
  // At this point, TypeScript knows status is 'never' if not all cases are handled
}
  1. Identify the union type causing the issue
  2. Use exhaustiveness checking with never
  3. Handle all union cases explicitly
  4. Use type predicates for complex narrowing
typescript — error
type Status = 'pending' | 'success' | 'error';
function handleStatus(status: Status) {
if (status === 'pending') {
// handle pending
} else if (status === 'success') {
// handle success
}
// At this point, TypeScript knows status is 'never' if not all cases are handled
}
Cannot access member 'x' for a type which is 'never'

What this error means

The 'never' type in TypeScript represents a type that has no values—an impossible state. When you see this error, it means TypeScript's control flow analysis has determined that your code should never reach that point. This commonly happens when: 1. You have a union type and forget to handle all possible cases 2. You have conditional type guards that don't cover all branches 3. TypeScript's type narrowing eliminates all possibilities before a certain line Accessing a property on 'never' is an error because logically, if a value can never exist, you can't access its properties. TypeScript is telling you something is wrong with your type logic, not your runtime code.

Typical symptoms

  • TypeScript compiler error mentioning 'never' type
  • Error message shows 'Cannot access member X for a type which is never'
  • The error appears in code that should be valid
  • Related to switch statements or conditional type checks
  • Missing cases in union type handling
  • Incomplete type guards in if/else chains

Common causes

  1. Unhandled union type cases (most common)
  2. Missing property in discriminated union type guard
  3. Type guard eliminates all possibilities in a branch
  4. Using arrow function with implicit 'never' return
  5. Exhaustiveness check failure with single-value unions
  6. Incorrect type narrowing with conditional types
  7. Missing case in switch statement with union types

How to fix "Cannot access member 'x' for a type which is 'never'"

1Identify the union type causing the issue

First, locate the variable with type 'never'. Check what union type led to this:

typescript
type Status = 'pending' | 'success' | 'error';

function handleStatus(status: Status) {
  if (status === 'pending') {
    // handle pending
  } else if (status === 'success') {
    // handle success
  }
  // At this point, TypeScript knows status is 'never' if not all cases are handled
}

Use your IDE's hover feature to see what type TypeScript infers at each point.

2Use exhaustiveness checking with never

Create an exhaustiveness check function that catches unhandled cases:

typescript
function assertNever(value: never): never {
  throw new Error(`Unhandled value: ${value}`);
}

type Status = 'pending' | 'success' | 'error';

function handleStatus(status: Status) {
  switch (status) {
    case 'pending':
      console.log('Pending...');
      break;
    case 'success':
      console.log('Success!');
      break;
    case 'error':
      console.log('Error occurred');
      break;
    default:
      assertNever(status); // TypeScript error if cases missing
  }
}

If you add a new status value to the union and forget to handle it in the switch, TypeScript will error at the assertNever call.

3Handle all union cases explicitly

With if/else chains, ensure every case is covered:

typescript
type Response = { type: 'success'; data: string } | { type: 'error'; error: Error };

function handleResponse(response: Response) {
  if (response.type === 'success') {
    console.log(response.data);
  } else if (response.type === 'error') {
    console.log(response.error);
  }
  // All cases covered, no 'never' type here
}

If you remove the else if block or don't handle all discriminator values, you'll get the 'never' error.

4Use type predicates for complex narrowing

For complex type guards, define explicit predicates:

typescript
interface Dog { type: 'dog'; bark(): void }
interface Cat { type: 'cat'; meow(): void }

type Animal = Dog | Cat;

function isDog(animal: Animal): animal is Dog {
  return animal.type === 'dog';
}

function isCat(animal: Animal): animal is Cat {
  return animal.type === 'cat';
}

function interact(animal: Animal) {
  if (isDog(animal)) {
    animal.bark();
  } else if (isCat(animal)) {
    animal.meow();
  }
  // TypeScript knows all cases are covered
}
5Verify with strict TypeScript settings

In tsconfig.json, ensure strict mode is enabled:

json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  }
}

Strict mode catches more type errors, including incomplete union handling.

Advanced notes

### Understanding 'never' in Type Narrowing

The 'never' type is the bottom type—assignable to every type, but no value is assignable to it. When TypeScript's control flow analysis exhausts all possible cases, the remaining type becomes 'never'.

typescript
type Literal = 'a' | 'b' | 'c';

function example(x: Literal) {
  if (x === 'a') {
    // x is 'a'
  } else if (x === 'b') {
    // x is 'b'
  } else if (x === 'c') {
    // x is 'c'
  } else {
    // x is 'never' — impossible to reach
  }
}

### Single-Value Union Edge Case

TypeScript has a known limitation: exhaustiveness checks work best with unions of 2+ members. Single-value unions sometimes don't trigger the 'never' type properly due to implicit any coercion.

Workaround: use a union of at least 2 types or force strict narrowing:

typescript
// Avoid:
type Single = 'only-value';

// Better:
type Single = 'only-value' | never;

### Discriminated Unions (Recommended Pattern)

For complex types, use discriminant properties:

typescript
type Result<T> =
  | { kind: 'success'; value: T }
  | { kind: 'error'; error: string };

function process<T>(result: Result<T>) {
  switch (result.kind) {
    case 'success':
      return result.value;
    case 'error':
      throw new Error(result.error);
    default:
      const _exhaustive: never = result;
      return _exhaustive;
  }
}

TypeScript uses the kind field to narrow the type, eliminating 'never' errors when properly handled.

### Async/Promise Edge Cases

'never' can appear with promise rejection handling:

typescript
async function fetchUser(id: string): Promise<never> {
  // This function never resolves or returns—it always throws or runs forever
  throw new Error('Not found');
}

Use Promise types for functions that might resolve.

Frequently asked questions

What does "Cannot access member 'x' for a type which is 'never'" mean?
The 'never' type in TypeScript represents a type that has no values—an impossible state. When you see this error, it means TypeScript's control flow analysis has determined that your code should never reach that point. This commonly happens when: 1.
How do I fix "Cannot access member 'x' for a type which is 'never'"?
This error occurs when TypeScript's type narrowing determines that a code path is unreachable (type 'never'), and you're attempting to access properties on it. The fix involves proper type guards and exhaustiveness checking.
What causes "Cannot access member 'x' for a type which is 'never'"?
Unhandled union type cases (most common) Missing property in discriminated union type guard Type guard eliminates all possibilities in a branch
Is the "Cannot access member 'x' for a type which is 'never'" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading