How to fix Type 'never' is not assignable to type 'string' in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025ยท 117 views

This error occurs when TypeScript infers a variable as the never type (representing impossible values) but you try to assign or use it where a string is expected, commonly from untyped empty arrays or over-narrowed type guards.

Quick fix

Fixes Type 'never' is not assignable to type 'string'

const items = [];
items.push("hello"); // Error: Argument of type 'string' is not assignable to parameter of type 'never'
  1. Add explicit type annotation to empty arrays
  2. Review type narrowing logic for unreachable branches
  3. Provide explicit types for generic function parameters
  4. Use type assertions for impossible states you know are safe
typescript โ€” error
const items = [];
items.push("hello"); // Error: Argument of type 'string' is not assignable to parameter of type 'never'
Type 'never' is not assignable to type 'string'

What this error means

The "Type 'never' is not assignable to type 'string'" error indicates that TypeScript has determined a value should be of type `never` (a type representing values that never occur) but you're trying to use it in a context expecting a `string`. The `never` type in TypeScript represents the type of values that never occur. When TypeScript infers `never`, it's typically because type narrowing through control flow analysis has eliminated all possible types, or because an empty array was declared without explicit typing, leading TypeScript to infer `never[]`. This means the array can never contain any elements according to TypeScript's analysis. This error commonly appears when working with arrays, conditional type narrowing, or union types where TypeScript's type inference becomes overly restrictive and narrows a type down to an impossible state. The compiler is essentially telling you that based on your code's logic, it believes no valid value can exist in this position, yet you're trying to treat it as a string.

Typical symptoms

  • Empty array operations fail with type errors when trying to push string values
  • Array indexing returns never type instead of expected element type
  • Conditional type guards eliminate all possible types leaving never
  • Type inference fails for array.reduce() or array.map() with empty arrays
  • React useState hook infers never[] for empty array initial state
  • Object property access returns never when all union branches are handled

Common causes

  1. Empty array declared without explicit type annotation, causing TypeScript to infer never[]
  2. Type narrowing through if/else or switch statements eliminates all possible union members
  3. Incorrect type guards that narrow a type to an impossible state
  4. Missing type annotation on useState or other generic hooks in React
  5. Array methods like reduce() with no initial value on an empty array
  6. Exhaustive type checking where all cases are handled but TypeScript expects a return value
  7. Using strictNullChecks mode with untyped empty arrays or objects

How to fix "Type 'never' is not assignable to type 'string'"

1Add explicit type annotation to empty arrays

The most common cause is declaring an empty array without typing it. TypeScript infers never[] which cannot hold any elements.

Before (causes error):

typescript
const items = [];
items.push("hello"); // Error: Argument of type 'string' is not assignable to parameter of type 'never'

After (fixed):

typescript
const items: string[] = [];
items.push("hello"); // OK

For React hooks:

typescript
const [items, setItems] = useState<string[]>([]);
setItems([...items, "hello"]); // OK
2Review type narrowing logic for unreachable branches

If type guards eliminate all possible types, TypeScript infers never. Check your conditional logic.

Problem code:

typescript
function processValue(value: string | number) {
  if (typeof value === "string") {
    return value.toUpperCase();
  } else if (typeof value === "number") {
    return value.toFixed(2);
  }
  // TypeScript infers 'value' is never here
  const result: string = value; // Error: Type 'never' is not assignable to type 'string'
  return result;
}

Fix: Remove unreachable code or add proper type assertion:

typescript
function processValue(value: string | number): string {
  if (typeof value === "string") {
    return value.toUpperCase();
  } else {
    return value.toFixed(2);
  }
  // No unreachable code
}
3Provide explicit types for generic function parameters

Generic functions like array methods may infer never when the type cannot be determined from context.

Problem:

typescript
const result = [].reduce((acc, item) => {
  acc[item] = item; // Error: never type
  return acc;
}, {});

Fix with explicit types:

typescript
interface Result {
  [key: string]: string;
}

const result = [].reduce<Result>((acc, item: string) => {
  acc[item] = item;
  return acc;
}, {});

Or provide initial type:

typescript
const items: string[] = [];
const result = items.reduce((acc, item) => {
  acc[item] = item;
  return acc;
}, {} as Record<string, string>);
4Use type assertions for impossible states you know are safe

If you know a value cannot actually be never at runtime, use type assertion as an escape hatch.

When TypeScript over-narrows:

typescript
function handleEvent(event: "click" | "hover") {
  if (event === "click") {
    // handle click
  } else if (event === "hover") {
    // handle hover
  } else {
    // TypeScript thinks this is unreachable (event is never)
    // But if you're adding new event types, this might execute
    const eventType: string = event as string; // Safe assertion
    console.warn(`Unknown event: ${eventType}`);
  }
}

Caution: Only use assertions when you understand why TypeScript inferred never and you're certain the code is correct.

5Check for missing discriminated union handling

With discriminated unions, failing to handle a case can result in never inference.

Problem:

typescript
type Response = 
  | { status: "success"; data: string }
  | { status: "error"; message: string };

function handleResponse(response: Response) {
  if (response.status === "success") {
    return response.data;
  }
  // Forgot to handle "error" case
  const msg: string = response.message; // Error: Property 'message' does not exist on type 'never'
}

Fix:

typescript
function handleResponse(response: Response): string {
  if (response.status === "success") {
    return response.data;
  } else {
    return response.message; // Now TypeScript knows this is the error case
  }
}
6Enable noImplicitAny to catch inference issues earlier

The TypeScript compiler option noImplicitAny helps prevent never type inference issues by requiring explicit types.

Update tsconfig.json:

json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

With noImplicitAny enabled, TypeScript will error on ambiguous empty arrays rather than silently inferring never[], forcing you to add explicit types:

typescript
// Will error without type annotation when noImplicitAny is true
const items: string[] = []; // Must explicitly type

This makes type errors surface earlier in development rather than when you try to use the values.

Advanced notes

Understanding never in the Type System

The never type is TypeScript's bottom type, meaning it's a subtype of every other type. Paradoxically, never is assignable to any type, but no type (except never itself) is assignable to never. This makes it useful for representing impossible states and exhaustiveness checking.

Empty Array Type Inference History

The inference of never[] for empty arrays has been debated in the TypeScript community (GitHub issues #18687, #20946, #51979). With strictNullChecks enabled, TypeScript cannot default to any[] or undefined[], so it chooses never[] to force developers to make explicit type decisions. While this prevents some bugs, it can be frustrating for beginners.

Library-Specific Issues

This error frequently appears in library contexts with complex generics:
- react-hook-form: useFieldArray can infer never for field names if types aren't properly constrained
- Redux: Action type inference sometimes resolves to never with incorrect reducer typing
- Styled-components: Variant props can infer never when extending component types

Exhaustiveness Checking Pattern

A common intentional use of never is for exhaustiveness checking in switch statements:

typescript
type Shape = Circle | Square | Triangle;

function area(shape: Shape): number {
  switch (shape.kind) {
    case "circle": return Math.PI * shape.radius ** 2;
    case "square": return shape.size ** 2;
    case "triangle": return (shape.base * shape.height) / 2;
    default:
      const _exhaustive: never = shape; // Compile error if we add a new Shape
      return _exhaustive;
  }
}

If you add a new shape type without handling it, TypeScript will error because the new type is not assignable to never.

Control Flow Analysis Limitations

TypeScript's control flow analysis is sophisticated but not perfect. It may not understand complex runtime logic, especially with:
- Indirect type guards through helper functions
- Complex boolean logic with multiple conditions
- Type predicates that don't narrow correctly

In these cases, explicit type annotations or assertions may be necessary even when the code is logically sound.

Frequently asked questions

What does "Type 'never' is not assignable to type 'string'" mean?
The "Type 'never' is not assignable to type 'string'" error indicates that TypeScript has determined a value should be of type never (a type representing values that never occur) but you're trying to use it in a context expecting a string. The never type in TypeScript represents the type of values that never occur. When TypeScript infers never, it's typically because type narrowing through control flow analysis has eliminated all possible types, or because an empty array was declared without explicit typing, leading TypeScript to infer never[].
How do I fix "Type 'never' is not assignable to type 'string'"?
This error occurs when TypeScript infers a variable as the never type (representing impossible values) but you try to assign or use it where a string is expected, commonly from untyped empty arrays or over-narrowed type guards.
What causes "Type 'never' is not assignable to type 'string'"?
Empty array declared without explicit type annotation, causing TypeScript to infer never[] Type narrowing through if/else or switch statements eliminates all possible union members Incorrect type guards that narrow a type to an impossible state
Is the "Type 'never' is not assignable to type 'string'" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading