Type 'string' is not assignable to type in TypeScript

avatar

Borislav Hadzhiev

Last updated: Jul 25, 2022

banner

Photo from Unsplash

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

The "Type 'string' is not assignable to type" TypeScript error occurs when we try to assign a value of type string to something that expects a different type, e.g. a more specific string literal type or an enum. To solve the error use a const or a type assertion.

Here is the first example of how the error occurs.

index.ts
type EmailStatus = 'draft' | 'read' | 'unread'; // 👇️ status has type `string` let status = 'draft'; status = 'read'; // ⛔️ Error: Type 'string' is not // assignable to type 'EmailStatus'.ts(2322) const current: EmailStatus = status; console.log(current);

The status variable has a type of string and the current variable has a type of EmailStatus.

When we try to assign a string to a variable that expects a value of type EmailStatus, we get the error.

TypeScript is telling us that the string type is too broad when one of the string literals draft, read or unread is expected.

To solve the error, use a type assertion to cast the string to be of type EmailStatus.

index.ts
type EmailStatus = 'draft' | 'read' | 'unread'; // 👇️ type is EmailStatus (not string) let status = 'draft' as EmailStatus; // 👈️ use type assertion status = 'read'; const current: EmailStatus = status; console.log(current); // 👉️ "read"

We used a type assertion to change the type of the status variable to EmailStatus which resolved the error.

The error occurs because, the string type has many more potential values than the EmailStatus type, which only covers 3 string literal values.

Let's look at another example of how the error occurs.

index.ts
type Letter = 'a' | 'b'; const arr: Letter[] = ['a', 'b']; const obj: { letter: string } = { letter: 'a', }; // ⛔️ Argument of type 'string' is not // assignable to parameter of type 'Letter'.ts(2345) arr.push(obj.letter);

The letter property in the object is typed as string and the array only expects strings of type Letter.

To solve the error, change the type of the letter property in the object to Letter or use a type assertion.

index.ts
type Letter = 'a' | 'b'; const arr: Letter[] = ['a', 'b']; const obj: { letter: string } = { letter: 'a', }; arr.push(obj.letter as Letter); // 👈️ type assertion

We used a type assertion to get around the error. However, it would be better if we could directly type the letter property in the object as Letter.

Let's look at another example of how the error occurs.

index.ts
type EmailStatus = 'draft' | 'read' | 'unread'; // 👇️ type is string[] const arr2 = ['unread']; const arr3: EmailStatus[] = ['draft', 'read']; // ⛔️ Error: Type 'string[]' is not // assignable to type 'EmailStatus[]'. const arr4: EmailStatus[] = [...arr2, ...arr3];

The arr2 variable has a type of string[], whereas arr4 has a much more specific type of EmailStatus[].

One way to solve the error is to use a const assertion.

index.ts
type EmailStatus = 'draft' | 'read' | 'unread'; // 👇️ type is readonly ["unread"] const arr2 = ['unread'] as const; const arr3: EmailStatus[] = ['draft', 'read']; const arr4: EmailStatus[] = [...arr2, ...arr3];
The as const syntax converts the array into a read-only tuple that contains a single string - unread. This might not be what you want if you have to change the contents of the array.

A more universal approach is to use a type assertion, as we did in the previous examples.

index.ts
type EmailStatus = 'draft' | 'read' | 'unread'; // 👇️ type is EmailStatus[] const arr2 = ['unread'] as EmailStatus[]; const arr3: EmailStatus[] = ['draft', 'read']; const arr4: EmailStatus[] = [...arr2, ...arr3];

Now the arr2 variable is typed as EmailStatus[] so we can unpack it into arr4.

Another common cause of the error is using enums with hardcoded strings.

index.ts
export enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } // ⛔️ Type '"READ"' is not assignable // to type 'EmailStatus'.ts(2322) const status: EmailStatus = 'READ';

The best way to get around this is to access the specific property on the enum if possible.

index.ts
export enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } // ✅ Solution 1 const status: EmailStatus = EmailStatus.Read; // ✅ Solution 2 const status2: EmailStatus = 'READ' as EmailStatus;

If, for some reason, you can't access the property on the enum, use a type assertion.

Enums are real objects that exist in runtime. The correct way to use them is to access their properties via dot or bracket notation.

Trying to use hardcoded strings with enums is a common cause of the error.

Conclusion #

The "Type 'string' is not assignable to type" TypeScript error occurs when we try to assign a value of type string to something that expects a different type, e.g. a more specific string literal type or an enum. To solve the error use a const or a type assertion.

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.