TypeScript Type Assertion Example
March 23, 2022
I was working on imprving D3 forceSimulation example and ran into an issue that required me to use a TypeScript type assertion. Which is something I haven’t done much of before and required some research. Actually, the truth is that I first had to figure out that I needed a type assertion to do what I was trying to do. That in itself took a few hours of combing through examples on GitHub to realize.
The scenario I found myself in was that I had an interface with a property who’s value was sometimes a number and sometimes another type. This can be a problem for TypeScript because the compiler doesn’t know which type I’m intending to use. The solution was to use a TypeScript type assertion to tell the compiler which type I’m using. This is typically done using the as
keyword or angle-bracket syntax.
interface Node {
id: number
x: number;
y: number;
}
interface Link {
source: Node | number
target: Node | number
}
const link1: Link = { source: 1, target: 2 }
// Property 'id' does not exist on type 'number | Node'.
// Property 'id' does not exist on type 'number'.ts(2339)
link1.source.x = 4
// TS compiler is happy because it knows the type is now
(link1.source as Node).x = 3
In the example shown above, D3 forceLink
is expecting a unique identifier to connect a link’s source and target to two nodes. In this case, the unique identifier is a number
that corresponds to the Node
type’s id
property. Later on in the code, the Link
type’s source
and target
properties need to have x
and y
coordinates set. This is when I tell the TypeScript compiler that I’m using the type Node
now instead of number
.
In this specific case with D3 and the forceLink
method, the identifier couldn’t be an object. It had to be a string
or number
as far as I can tell. Otherwise I wouldn’t need the TypeScript union and I could just set the source
and target
type’s to be of type Node
.