How to cast custom type into primitive type in typescript?

How to cast custom type into primitive type in typescript?


Types are actually the soul of TypeScript, typescript came into the game to give power to JavaScript, and that makes Typescript a success. You can read my article on why you should move from JavaScript to TypeScript. But most developers gave up as it is a bit difficult different that causes developers to lose hope at the beginning of their journey. One of the many problems that devs usually came across is assigning a type to a different type; typescript is a little strict. It has become better at auto type casting in newer versions. Still, it needs manual typecasting, which we are going to discuss here. If you don't want to dive in deeper, you can skip to the quick solution. We will discuss what a primitive type is and what is a custom type, what is type casting, and what is an unknown type in TypeScript.

Related article: NextJS - from React.js to an ultra-fast experience

Custom type to primitive type: Quick Solution

Photo by Nelly Karina Lopez on Unsplash

Let's take an example. There's a type called Color and there's a string variable say input.

// Test
type Color = 'Black' | 'White' | 'Red' | 'Green' | 'Blue';

const input: string = 'Black';

Now suppose you want to store the input into a variable phoneColor of type Color, typescript won't allow it. It'll throw an error

Type 'string' is not assignable to type 'Color'.ts(2322)

Now here you have to cast the custom type Color into the primitive type string as follows.

const phoneColor: Color = input as Color;

That's it, is the job done? Yes and No. Yes as the job is done but no because there will be some cases where you cannot directly cast custom to a primitive type. In those cases, the typescript compiler throws an error

Conversion of type Color to type number may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.ts(2352)

The error contains the solution to it. As it says, you have to convert the expression into unknown first. Casting some type to unknown removes its initial type and make it assignable to any other type.

const phoneColor: Color = input as unknown as Color;

You can mark it. This solution works everywhere.

What are primitive types and custom types?

Photo by Sam Carter on Unsplash

Every language (not really every) specifies some inbuilt types, and all the data belongs to those types. But as the complexity grows, developers needed their own defined complex types. Language has to define a way to communicate between these custom types with the pre-defined types (or primitive types). Let's see what these types are and what the difference is.

Primitive Types

 Whenever we save some data into a variable, say we saved some number, or boolean or characters (string), language automatically defines the type from the value. They are already defined in the language specification and not created by you. These are called basic types or primitive types, for example.

const batman: string = 'Bruce Wayne';

const friday: number = 13;

const isBatman: boolean = true;

There are 12 basic types defined by TypeScript as per current their documentation TS version 4.0. You can read it all the 12 basic types here.

Custom Types

Custom types or user-defined types are complex types made from primitive types. Suppose there's a variable to save a person's age; you can simply guess the type of the variable would be number. But what will be the type of variable to store the phone number of a person along with the country code, string, number, or what? Here comes the role of a custom type. The developer has to define a whole new type and assign a name to it.

interface PhoneNumber {
    countryCode: string;
    phone: string;

So, you can define a new type, say PhoneNumber, and by looking at its structure, it is clear that it can store both the information countryCode as well as the phone number of the user.

interface PhoneNumber {
    countryCode: string;
    phone: string;

const ph1:PhoneNumber = {
    countryCode: '+1',
    phone: '9876543210'

So there are scenarios where the user has to define its own custom type, made of primitive types. But there are cases where primitive types have to communicate (assign or any other operation) to the custom type. And then casting comes into play. Let's see what casting is in the next section.

What is typecasting?

what is typecasting in typescript
Photo by Les Triconautes on Unsplash

In simple words, we can define, typecasting is the conversion of a type into another type. That's it, it is called typecasting. But it is not as simple as it sounds. The compiler is smart many times, where it cast the types internally without any dev intervention. See the example below.

type Rate = 1 | 2 | 3 | 4 | 5;

const rating: Rate = 3;

const value:number = rating;

Even though we are assigning a Rate type to number type, the compiler knows that Rate is a subset of number and all the possible values of type Rate is assignable to a number. But the reverse is not true.

type Rate = 1 | 2 | 3 | 4 | 5;

const value: number = 3;

const rating: Rate = value;

It will throw the error Type 'number' is not assignable to type 'Rate'.ts(2322).  

Even though 3 satisfies the Rate type, the type of value is number, and all the possible values of type number cannot be assigned to Rate. But still, 3 should be assignable to Rate. So in such cases, we have to cast the custom type to the primitive type manually as shown below.

const rating: Rate = value as Rate;

Now we have manually told the compiler, that convert (cast) the number type into Rate type so that it is assignable to the Rate type variable. And it will now work smoothly. But again it won't work everywhere like you cannot assign a boolean type toa string by manually casting, Compiler won't allow that, but if you still want to do it, you have to bluff the compiler by removing the type first and assigning a new type as shown below.

type Rate = 1 | 2 | 3 | 4 | 5;

const value: number = 3;

const rating: Rate = value as unknown as Rate;

This way will never fail, but it is discouraged and should only be used in worst scenarios. But what was that unknown? Let's see.

What is the unknown type in typescript?

unknown type typescript
Photo by Steve Johnson on Unsplash

As of now, we have seen the use of unknown type. But haven't really defined it yet. So as its name depicts, unknown type is given to those whose type is not known and can be given any other type. In most of the places where the type is not known, typescript adds any type implicitly. Both any and unknown types are similar, except any is assignable to any other type but you cannot assign unknown to other types. That's where it was needed. You have to assign some type to unknown type variable before assigning it to another type.


© 2021 Garbage Valuegarbage value logo