Argument of type not assignable to parameter type 'never'

avatar
Borislav Hadzhiev

Last updated: Feb 29, 2024
8 min

banner

# Table of Contents

  1. Argument of type not assignable to parameter type 'never'
  2. Type is not assignable to type 'never' in TypeScript
  3. Type is not assignable to type 'never' in React.js

This article covers 3 errors, so make sure to click on the relevant to you subheading depending on if you use TypeScript or React.js.

# Argument of type not assignable to parameter type 'never'

The error "Argument of type is not assignable to parameter of type 'never'" occurs when we declare an empty array without explicitly typing it and attempt to add elements to it.

To solve the error, explicitly type the empty array, e.g. const arr: string[] = [];.

not assignable to parameter type never

Here are 2 examples of how the error occurs.

index.ts
const arr = []; // ⛔️ Error: Argument of type 'number' is not assignable to parameter of type 'never'.ts(2345) arr.push(100); // --------------------------------------- const obj = { arr: [], }; // ⛔️ Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345) obj.arr.push('one');

We declared an empty array and it got assigned a type of never[]. This type represents an array that will never contain any elements (will always be empty).

# Explicitly type the array to solve the error

To solve the error, explicitly type the empty array.

index.ts
const arr: number[] = []; arr.push(100); console.log(arr); // 👉️ [100] // --------------------------------------- type MyType = { arr: string[]; }; const obj: MyType = { arr: [], }; obj.arr.push('one'); // 👇️ {arr: ['one']} console.log(obj);

explicitly type the array to solve the error

The code for this article is available on GitHub

We typed the first array as number[]. In other words, an array containing only number elements.

index.ts
const arr: number[] = [];

The arr property in the second example is an array containing strings - string[].

I've written a detailed guide on how to declare an empty array for a typed variable in TS.

# Using the any type to disable type checking

If you don't know what type of elements your array contains and would like to disable type checking, type the array as any[].

index.ts
const arr: any[] = []; arr.push(100); arr.push('hello'); arr.push({ name: 'James' }); // 👇️ [100, 'hello', {name: 'James'}] console.log(arr);

using any type to disable type checking

The code for this article is available on GitHub

This effectively disables type checking, which means the array can contain elements of any type.

# Typing an array of objects

Here is an example of how you would type an array of objects.

index.ts
const arr: { id: number; name: string }[] = []; arr.push({ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }); // 👇️ [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}] console.log(arr);

typing an array of objects correctly

Each object in the array contains the id and name properties.

You can also extract the type of the object into a type alias or an interface.

index.ts
type Person = { id: number; name: string; }; const arr: Person[] = []; arr.push({ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }); // 👇️ [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}] console.log(arr);

If you need to type an array of objects, check out my detailed guide.

# An empty array is inferred to have a type of never[]

The error occurs because when we declare an empty array, TypeScript infers its type to be never[] - an array that will never contain any elements.

index.ts
// 👇️ const arr: never[] const arr = []; // 👇️ const obj: { // arr: never[]; // } const obj = { arr: [], };
The code for this article is available on GitHub

# Changing this behavior in your tsconfig.json file

However, TypeScript infers the type of the variables that store an empty array differently depending on the settings in your tsconfig.json file.

When you set noImplicitAny to false and strictNullChecks to true, the type of an empty array is inferred to be never[].

tsconfig.json
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": false, // ... rest } }

However, if I switch noImplicitAny to true, the type of a variable that stores an empty array is inferred to be any[].

tsconfig.json
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": true, // ... rest } }

Now the arr variable is inferred to be any[].

index.ts
// 👇️ const arr: any[] 👇️ const arr = []; // 👇️ const obj: { // arr: never[]; // } const obj = { arr: [], };

Notice that variables that store an empty array now have an inferred type of any[].

In other words, an array with type-checking disabled (can contain any type of elements).

However, the empty array property in the object is still of type never[].

The noImplicitAny option causes TypeScript to issue an error when no type annotations for a value are present, so it has to implicitly infer its type to any.

This behavior is very unintuitive and it's best to not rely on something like this.

It is always a best practice to explicitly type empty arrays or objects when you declare them.

You can rely on TypeScript to infer the type of literals (e.g. strings and numbers) that you declare inline, but it's never a good idea to do that for arrays or objects.

If you try to access a property on a value that has a type of never, you'd get the Property does not exist on type 'never' error.

If you got the error Type is not assignable to type 'never' in React.js, click on the following subheading:

# Type is not assignable to type 'never' in TypeScript

The error "Type is not assignable to type 'never'" occurs when we declare an empty array without explicitly typing it and then attempt to mutate the array.

To solve the error, explicitly type the empty array.

type is not assignable to type never

Here is an example of how the error occurs.

index.ts
// 👇️ const arr: never[] const arr = []; // ⛔️ Error: Type 'string' is not assignable to type 'never'.ts(2322) arr[0] = 'a';

We declared an empty array and it got assigned a type of never[]. This type represents an array that will never contain any elements (will always be empty).

# Explicitly type the array to solve the error

To solve the issue, explicitly type the empty array.

index.ts
const arr: string[] = []; arr[0] = 'a'; console.log(arr); // 👉️ ['a']

explicitly type array to solve the error

The code for this article is available on GitHub

We typed the array as string[], in other words, an array containing only strings.

If you don't know what type of elements your array contains and would like to disable type checking, you can type it as any[].

index.ts
const arr: any[] = []; arr[0] = 'a'; arr[1] = 100; arr[2] = { department: 'development' }; // 👇️ ['a', 100, {department: 'development'}] console.log(arr);

disable type checking by using any array

This effectively disables type checking, which means the array can contain elements of any type.

Here is an example of how you would type an array of objects.

index.ts
const arr: { name: string; salary: number }[] = []; arr[0] = { name: 'Tom', salary: 100 }; arr[1] = { name: 'Tim', salary: 200 }; // 👇️ [{name: 'Tom', salary: 100}, {name: 'Tim', salary: 200}] console.log(arr);

Each of the objects in the array has name and salary properties.

You can also extract the type of the object into a type alias or an interface.

index.ts
type Employee = { name: string; salary: number; tasks: string[]; }; const arr: Employee[] = []; arr[0] = { name: 'Tom', salary: 100, tasks: ['task 1'] }; arr[1] = { name: 'Tim', salary: 200, tasks: ['task 2', 'task 3'] };

The reason the error occurs is that when we declare an empty array, TypeScript infers its type to be never[] - an array that will never contain any elements.

index.ts
// 👇️ const arr: never[] const arr = []; // 👇️ const employee: { // tasks: never[]; // } const employee = { tasks: [], };

Check out the following article if you'd like to read more on declaring an empty array for a typed variable.

# The noImplicitAny setting in tsconfig.json

However, TypeScript infers the type of the variables that store an empty array differently depending on the settings in your tsconfig.json file.

When you set noImplicitAny to false and strictNullChecks to true, the type of an empty array is inferred to be never[].

tsconfig.json
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": false, // ... rest } }

However, if I switch noImplicitAny to true, the type of a variable that stores an empty array is inferred to be any[].

tsconfig.json
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": true, // ... rest } }

Now the arr variable is inferred to be any[].

index.ts
// 👇️ const arr: any[] const arr = []; // 👇️ const employee: { // tasks: never[]; // } const employee = { tasks: [], };

Notice that variables that store an empty array now have an inferred type of any[], in other words, an array with type checking disabled (can contain any type of elements).

However, the empty array property in the object is still of type never[].

The noImplicitAny option causes TypeScript to issue an error when no type annotations for a value are present, so it has to implicitly infer its type to any.

This behavior is very unintuitive and it's best to not rely on something like this.

It is always a best practice to explicitly type empty arrays of objects when you declare them.

You can rely on TypeScript to infer the type of literals (e.g. strings and numbers) that you declare inline, but it's never a good idea to do that for arrays or objects.

# Type is not assignable to type 'never' in React

The error "Type is not assignable to type 'never'" occurs when we declare an empty state array with the useState hook but don't type the array.

To solve the error, use a generic to type the state array.

Here is an example of how the error occurs.

App.tsx
import {useState} from 'react'; function App() { // 👇️ arr is never[] const [arr, setArr] = useState([]); // ⛔️ Error: Type 'number' is not assignable to type 'never'.ts(2322) setArr([1, 2, 3]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;

The error was caused because we declared an empty state array without explicitly typing it.

The type of the array is inferred to be never[], in other words, an array that will always be empty, which is not what we want.

# Type the state array with a generic

To solve the error, use the generic on the useState hook to type the state array.

App.tsx
import {useState} from 'react'; function App() { // 👇️ type the array with the generic const [arr, setArr] = useState<any[]>([]); setArr([1, 2, 3]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;

We used the very broad type of any[], which is an array containing elements of any type.

It's always better to be more specific when possible.

App.tsx
import {useState} from 'react'; function App() { // 👇️ array of strings const [strArr, setStrArr] = useState<string[]>([]); // 👇️ an array of objects const [objArr, setObjArr] = useState<{name: string; age: number}[]>([]); setStrArr(['a', 'b', 'c']); setObjArr([{name: 'A', age: 1}]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;

The examples above show how to type the state array as an array of strings or an array of objects.

Always make sure to explicitly type empty arrays in React when using TypeScript.

If you get an error message that contains the never type, there's a very good chance that you have forgotten to explicitly type a value and it is inferred to have a type of never.

To debug this, hover over the value to see its type and look for ways to explicitly type it. If you're working with react hooks, there's a very good chance you have to use a generic as we did with the useState hook.

If you are typing a basic TypeScript variable, just separate the variable name and its type with a colon.

App.tsx
function App() { // 👇️ declare array of strings const arr: string[] = []; arr.push('a', 'b', 'c'); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;

I've also written a detailed article on how to type useState as an array or object.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.