Fix - Type 'string' is not assignable to type in TypeScript

avatar

Borislav Hadzhiev

Sun Mar 06 20223 min read

banner

Photo by Jake Melara

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

The "Type 'string' is not assignable to type" TypeScript error occurs when we are trying 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);

Notice that 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 an error.

TypeScript is telling us that the type string is too generic 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 solves 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, you can 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 you 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 readonly 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, like 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 error is to access the specific property in 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.

Use the search field on my Home Page to filter through my more than 1,000 articles.