DEV Community

Cover image for Type Casting in TypeScript
Johnny Simpson
Johnny Simpson

Posted on • Originally published at fjolt.com

Type Casting in TypeScript

Sometimes, in TypeScript, something will have an unknown type where TypeScript can't discern the specific type something should be. At it's most basic, this can occur when a variable is simply given the type unknown. For example:

let text:unknown = "String Goes Here";
Enter fullscreen mode Exit fullscreen mode

Although we can see that the type of the content above is a string, it has been given the type unknown, so TypeScript doesn't know what type it is. As such, when we try to run methods on this that are string specific, they won't work. Let's say we wanted to get the length of this string, for example:

let text:unknown = "string";
let value = text.length;
Enter fullscreen mode Exit fullscreen mode

How Casting works in TypeScript

The code above will actually throw an error, which is Object is of type 'unknown'.. To solve this problem, we need to use TypeScript casting. To cast something in TypeScript, we use the as keywords. For this example, we need to cast the text variable to a string, so TypeScript will let us use length:

let text:unknown = "string";
let value = (text as string).length;
Enter fullscreen mode Exit fullscreen mode

Now TypeScript will case the type to string, and we can use length. The way this code is written is unlikely to happen in the real world, but it could occur if you receive an API response of unknown type, and have to conform it to a type.

Another common place this happens, is with selectors. For example, it's pretty common to select an input, and expect to be able to find the value via the value property:

let input = document.querySelector('input');
let inputValue = input.value;
Enter fullscreen mode Exit fullscreen mode

In TypeScript this throws an error, since Object is possibly 'null'.. TypeScript has a number of predefined types for query selector outputs, but we can't write let input:HTMLInputElement = ... either, since the input is possibly null. As such, we have to cast the input to HTMLInputElement to get the value:

let input = document.querySelector('input') as HTMLInputElement;
let inputValue = input.value;
Enter fullscreen mode Exit fullscreen mode

Conclusion

I hope you've enjoyed this tutorial. TypeScript casting is necessary in some situations, especially when using querySelector. It's a useful way to enforce certain type restrictions on outputs from APIs, or variables with unknown types.

Top comments (5)

Collapse
 
brense profile image
Rense Bakker

This code:

const input = document.querySelector('input')
Enter fullscreen mode Exit fullscreen mode

Already yields correctly typed: const input: HTMLInputElement | null

Type casting opens up your code for runtime errors, it's better to just check if the element is null when you want to use it:

const inputValue = input?.value
Enter fullscreen mode Exit fullscreen mode

Results in inputValue having the correct type: const inputValue: string | undefined

Collapse
 
smpnjn profile image
Johnny Simpson

I don't think there's anything inherently wrong with casting an input to type HTMLInputElement in this example, although your example will also work and is another solution to the problem.

Type assertion It is one of the recommended ways to assert types like this in the TypeScript handbook and as mentioned, "Because type assertions are removed at compile-time, there is no runtime checking associated with a type assertion. There won’t be an exception or null generated if the type assertion is wrong."

typescriptlang.org/docs/handbook/2...

Collapse
 
ecyrbe profile image
ecyrbe • Edited

What Rense meant is that by typecasting, you open your code to runtime errors.

Imagine you have an element of type
HTMLElement and you type cast it as HTMLInputElement when in fact it's not. Calling CheckValidity() on it will cause a runtime error unless you checked at runtime it's actually an input element.

So in typescript, instead of typecasting, you should use a type predicate that does a runtime check.
And obviously when an API tells you that the result could be null, instead of typecasting you should check if it's actually null or not.

Thread Thread
 
smpnjn profile image
Johnny Simpson

Ah ok, makes sense now. I will update at some point to include that info.

Collapse
 
brense profile image
Rense Bakker

If you type cast something that can also be null and it turns out to be null when you run the code, you get a runtime error.