Typescript Type 'string' is not assignable to type
Here's what I have in fruit.ts
export type Fruit = "Orange" | "Apple" | "Banana"
Now I'm importing fruit.ts in another typescript file. Here's what I have
myString:string = "Banana";
myFruit:Fruit = myString;
When I do
myFruit = myString;
I get an error:
Type 'string' is not assignable to type '"Orange" | "Apple" | "Banana"'
How can I assign a string to a variable of custom type Fruit?
Solution 1:
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;
Solution 2:
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.
Solution 3:
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
.