Working with DOM and type casting
Working with DOM and type casting

In this video you will learn to work with DOM using Typescript. So let's jump right into it.

In previous video we already talked a little bit about type assertion and type casting. If you didn't want it the pause this video and watch that first.

So just to remind you we can tell Typescript that we want to use other type that what is there. It's especially useful when we got incorrect type from some library that we can't fix.

let page: any = "1";
let pageNumber = page as string;

Let's say that from some library we got page which is any. Of course it's bad to work with any because Typescript doesn't check anything. This is why we cast the type to string using as keyword. Now pageNumber has a correct type.

const someElement = document.querySelector("foo");

As you can see all things are magically typed out of the box with Typescript. So we don't need to install additional libraries or types. Here we can see a document and a querySelector method which returns us element. But the most important to remember is that Typescript doesn't do anything with markup. It doesn't know if we have this element or not. It just knows the types that we define. This is why we can't read some properties from element. Because Element is the general class for all existing elements.

const someElement = document.querySelector(".foo");

console.log("someElement", someElement.value);

But we can specify what is the element exactly using type casting.

const someElement = document.querySelector(".foo") as HTMLInputElement;

console.log("someElement", someElement.value);

Because we said that it's HTMLInputElement now we can get all things that we can normally read from input. Like value for example.

A lot of people which start using Typescript (especially inside Angular) are writing as any because they didn't learn Typescript properly and they don't understand why they can't read values from Element and they this that Typescript is dumb.

Let's try to add a blur event for our input to check how Typescript covers everything.

So here we see addEventListener and it exists even on Element because it is allowed on all DOM elements. Now are you can see we get a lot of important information from Typescript that helps us to use method correctly.

const someElement = document.querySelector(".foo");

someElement.addEventListener("blur", (event) => {
  console.log("event", event);
});

What is interesting to check is that event type changes based on someElement type. If it's an Element we get a generic Event but if we change our element to HTMLInputElement then we immediately get FocusEvent which is correct because it's the event which we are getting when we work with inputs.

Most often we want to read a value of the input. But here we have the most common Typescript problem with DOM elements. So normally we want to read event.target.value. But here we are getting Typescript error.

console.log("event", event.target.value);
Property 'value' does not exist on type 'EventTarget'

The problem is the same like with Element on the top. Typescript doesn't know what event.target is and we are getting generic EventTarget here which doesn't have value properly. To be able to use it we need to say to Typescript that it's an HTMLInputElement. So let's cast the correct type.

const target = event.target as HTMLInputElement;
console.log("event", target.value);

Now we don't have any errors.

And of course we have correct typings for all DOM elements in Typescript so you can type correctly every element that you are using.

As you can see working with Typescript is not easy and you need to check a lot of standard types to understand how it all works together and what to do if you are getting some Typescript error.

Also if you want to improve your programming skill I have lots of full courses regarding different web technologies.

📚 Source code of what we've done