Type is not assignable to type 'never' in TypeScript

avatar

Borislav Hadzhiev

Last updated: Mar 20, 2022

banner

Photo from Unsplash

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 attempt to mutate the array. To solve the error, explicitly type the empty array, e.g. const arr: string[] = [];.

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).

To solve this, we have to explicitly type the empty array.

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

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);

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 "Argument of type is not assignable to parameter of type 'never'" occurs is because when we declare an empty object, 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: [], };
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.

Conclusion #

The error "Type is not assignable to type 'never'" occurs when we declare an empty array without explicitly typing it and attempt to mutate the array. To solve the error, explicitly type the empty array, e.g. const arr: string[] = [];.

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.