DEV Community

kay-adamof
kay-adamof

Posted on

[TypeScript] How to create a union type consisting of string literals and string primitive

Let's consider a way to specify specific strings like 'dog' or 'cat' as literal types while including other string types when creating types in TypeScript.

Let's start with a simple type:

type AnimalWithString = 'dog' | 'cat' | string
// type Animal = string
Enter fullscreen mode Exit fullscreen mode

In this case, the type information for Animal becomes type Animal = string, which loses the information about 'dog' or 'cat'. This is not useful.

Let's remove the string type:

type Animal = 'dog' | 'cat'
// type Animal = "dog" | "cat"
const myAnimal:Animal = 'bird'
//Type '"bird"' is not assignable to type 'Animal'.(2322)
Enter fullscreen mode Exit fullscreen mode

Now it becomes a simple union of literal types, and it won't accept other strings like 'bird'.

So let's use a technique.

Instead of string, we'll use (string & {}).

type AnimalSpecified = 'dog' | 'cat' | (string & {})
// type AnimalSpecified = "dog" | "cat" | (string & {})
const animalIncludingMightBe:AnimalSpecified = 'bird'
Enter fullscreen mode Exit fullscreen mode

With this, we can maintain 'dog' and 'cat' while providing the information of the string type, creating a type that has both string literal types and string types.

Please try it out in the TS Playground to see its actual behavior.

In (string & {}), {} refers to a type that is non-null and non-undefined. By creating an intersection type with string using &, TypeScript can maintain the string type.

I learned about this method from this StackOverflow question and answer.

If you have any other better solutions, please let me know.

That's all.

Top comments (0)