Type Casting vs. Type Assertions in TypeScript
A teammate asked why casting a form value
as A
didn’t remove extra fields. The question exposed a gap in my own understanding, so I dug in. Here’s what I found.
Reproducing the Issue
We declare type A
with four properties but the form returns five. Casting with as A
doesn’t strip the extra field:
height
sticks around. Deleting the property manually works, but why?
No Runtime Casting in TypeScript
TypeScript is a superset of JavaScript. There’s no runtime type conversion—only type assertions and type inference. as Foo
and <Foo>
are assertions. They do not change the runtime object.
Type Assertions
let foo: any;
let bar = foo as string; // bar is typed as string
In JSX/TSX, prefer as
syntax to avoid conflicts with JSX tags.
Assertions tell the compiler what you, the developer, believe the type to be. They don’t alter runtime data.
Type Conversions?
If you actually need to remove properties, you must do it manually (e.g., copy only allowed fields). TypeScript won’t do it for you.
Type Inference
TypeScript infers types when possible (variable declarations, return values, destructuring, etc.). It reduces boilerplate, but for complex cases I still recommend explicit annotations.
How TypeScript Compiles
TypeScript adds a type system but ultimately emits JavaScript. The diagram from “Programming TypeScript” illustrates the pipeline:
Contrast with Java Casting
Java performs runtime casts (widening/narrowing). For example, casting a subclass to a parent can hide properties.
TypeScript, being JavaScript-based, behaves differently.
Final Thoughts
TypeScript isn’t Java; keep its model in mind. Understand assertions vs. conversions, embrace type inference responsibly, and manipulate runtime data explicitly when needed.