← Back to TypeScript Course | Chapter 12: TypeScript with DOM | Lesson 4 of 6

Type Casting DOM Elements

DOM APIs sometimes return general element types even when you know the exact HTML element. Type assertions can tell TypeScript about that known type, while runtime checks are safer when the type is uncertain.

Casting with as

The as keyword tells the compiler to treat a value as a more specific type than it inferred, which is how you turn a generic Element into a concrete type like HTMLInputElement when you're confident about the DOM structure.

Example: Casting with as

typescript
const el = document.createElement("input") as HTMLInputElement;
el.value = "typed";
console.log(el.value);

Casting querySelector Results

Casting the result of querySelector with as HTMLButtonElement is a common pattern since querySelector's return type is too generic on its own to expose button-specific properties like .disabled.

Example: Casting querySelector Results

typescript
document.body.innerHTML = '<button class="submit" disabled></button>';
const btn = document.querySelector(".submit") as HTMLButtonElement;
console.log(btn.disabled);

Checking Before Casting

Checking an element's actual type at runtime — for example with instanceof HTMLInputElement — before touching input-specific properties gives you real safety that a blind as cast doesn't, since the check can actually fail gracefully.

Example: Checking Before Casting

typescript
const el: Element = document.createElement("input");
if (el instanceof HTMLInputElement) {
  console.log(el.value);
}

Non-Null Assertions

A non-null assertion (element!) tells the compiler to stop worrying that a value might be null, which is convenient but dangerous, since it suppresses a real check the runtime will still enforce if you're wrong.

Example: Non-Null Assertions

typescript
document.body.innerHTML = '<div id="app"></div>';
const el = document.getElementById("app")!;
console.log(el.id);

Avoiding Unsafe Casts

Avoid casting to a type that isn't actually guaranteed by the DOM structure — an incorrect as cast compiles cleanly but shifts the failure to a runtime crash on .value or similar, exactly the class of bug static typing exists to prevent.

Example: Avoiding Unsafe Casts

typescript
const el = document.createElement("div") as unknown as HTMLInputElement;
// This compiles cleanly but el.value doesn't really exist on a div at runtime.
console.log((el as any).value);
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.