There's no type casting in TypeScript
TL;DR: There’s only type assertion!
An example
Consider this piece of code:
interface X {
y: number
}
let obj = JSON.parse(`{"a": 1}`);
console.log(obj as X);
This program can successfully compile and run
with no report of error.
But something is obviously wrong here: the parsed object obj
doesn’t have the
property y
, so “casting” it to type X
should fail.
Why?
The as
keyword is for type assertion
, not type “casting”.
Here, we use the type assertion syntax and tell the compiler
that we are sure that obj
has type X
, so that the rest of the code can type
check based on this assumption.
This also applies to other type assertion syntax in TypeScript, like:
let obj: X = JSON.parse(`{"a": 1}`);
This counters my intuition about typed programming languages. In other typed languages, there’s rarely such type assertion. Consider these Java statements:
jshell> Object a = 1;
a ==> 1
jshell> String b = (String) a;
| Exception java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
| at (#2:1)
Here, casting an object with the wrong class will throw a ClassCastException
. In Golang,
unmarshal-ing a JSON object to a struct may also fail.
The Correct Way
The Rule of Thumb is: only use type assertions when you’re sure about it .
If you’re looking for a way to cast an unknown object to a known schema, you might want to check out tools for schema validation, like Yup and Joi .
Edited (17 Oct 2022): Make the article more concise.