Typescript Type 'string' is not assignable to type Typescript Type 'string' is not assignable to type angular angular

Typescript Type 'string' is not assignable to type


You'll need to cast it:

export type Fruit = "Orange" | "Apple" | "Banana";let myString: string = "Banana";let myFruit: Fruit = myString as Fruit;

Also notice that when using string literals you need to use only one |

Edit

As mentioned in the other answer by @Simon_Weaver, it's now possible to assert it to const:

let fruit = "Banana" as const;


Typescript 3.4 introduced the new 'const' assertion

You can now prevent literal types (eg. 'orange' or 'red') being 'widened' to type string with a so-called const assertion.

You will be able to do:

let fruit = 'orange' as const;  // or...let fruit = <const> 'orange';

And then it won't turn itself into a string anymore - which is the root of the problem in the question.

Bonus Tip: You can also use <const> false or <const> true to represent a boolean that must be true or false. This can be useful in discriminated unions sometimes. You'll know it when you see it.


When you do this:

export type Fruit = "Orange" | "Apple" | "Banana"

...you are creating a type called Fruit that can only contain the literals "Orange", "Apple" and "Banana". This type extends String, hence it can be assigned to String. However, String does NOT extend "Orange" | "Apple" | "Banana", so it cannot be assigned to it. String is less specific. It can be any string.

When you do this:

export type Fruit = "Orange" | "Apple" | "Banana"const myString = "Banana";const myFruit: Fruit = myString;

...it works. Why? Because the actual type of myString in this example is "Banana". Yes, "Banana" is the type. It is extends String so it's assignable to String. Additionally, a type extends a Union Type when it extends any of its components. In this case, "Banana", the type, extends "Orange" | "Apple" | "Banana" because it extends one of its components. Hence, "Banana" is assignable to "Orange" | "Apple" | "Banana" or Fruit.