Skip to content

타입스크립트와 DOM

1. DOM (Document Object Model)

  • DOM은 HTML 문서를 트리 구조의 객체로 표현한 모델이다.
    각 HTML 요소는 JavaScript에서 객체로 다룰 수 있다.
  • TypeScript는 DOM API를 위한 타입 정의(lib.dom.d.ts)를 기본적으로 제공한다.
    → 예를 들어, document.querySelector, HTMLElement, Event, NodeList 등은 이미 타입이 정의되어 있다.
  • 브라우저 환경에서 실행되는 코드라면, TypeScript는 자동으로 DOM 타입을 인식한다.
    (Node.js 환경에서는 별도로 dom 라이브러리 설정이 필요함)
ts
// HTMLElement | null
const link = document.getElementById("myLink");

// HTMLButtonElement (타입 단언)
const btn = document.getElementById("btn") as HTMLButtonElement;

// HTMLParagraphElement
const p = document.createElement("p");

2. 타입스크립트와 DOM

  • TypeScript는 JavaScript에서 제공하는 모든 DOM API를 그대로 사용할 수 있다.
  • lib.dom.d.ts 파일을 통해 정적 타입 체크와 자동 완성을 지원한다.
ts
const link1 = document.getElementById("myLink");
const link2 = document.querySelector("#myLink");

// Error 발생
if (link1) {
  link.href = ""; // Property 'href' does not exist on type 'HTMLElement'
}

if (link2) {
  link2.href = ""; // Property 'href' does not exist on type 'Element'
}
ts
const link1 = document.getElementById("myLink") as HTMLAnchorElement;
const link2 = document.querySelector("#myLink") as HTMLAnchorElement;

link1.href = "https://google.com";
link2.href = "https://naver.com";
html
<a id="myLink" href="https://google.com">google</a>
  • getElementByIdHTMLElement | null 반환
  • querySelectorElement | null 반환
  • 즉, TypeScript는 해당 요소가 <a> 태그인지 확신할 수 없기 때문에 href 프로퍼티에 접근하려면 타입 단언이 필요하다.

3. createElement와 제네릭

TypeScript는 DOM 메서드마다 구체적인 타입을 반환한다.

ts
const img = document.createElement("img"); // HTMLImageElement
img.src = "image.png";

const anchor = document.createElement("a"); // HTMLAnchorElement
anchor.href = "https://example.com";
  • document.createElement()는 태그 이름에 따라 자동으로 해당 요소 타입을 추론한다.

ts
const div = document.querySelector<HTMLDivElement>("div"); // HTMLDivElement | null
const buttons = document.querySelectorAll<HTMLButtonElement>("button");

buttons.forEach((button) => {
  button.click(); // 자동 완성됨
});
  • querySelector는 제네릭으로도 타입을 명시할 수 있다.
  • 제네릭을 사용하면 명시적인 타입 단언(as HTMLDivElement) 없이도 타입을 추론할 수 있다.

4. 이벤트 핸들링

이벤트 리스너 역시 TypeScript가 제공하는 이벤트 객체 타입을 사용할 수 있다.

html
<div id="myDiv"></div>
ts
const myDiv = document.getElementById("myDiv");

myDiv?.addEventListener("click", (e: Event) => {
  // MouseEvent
  if (e instanceof MouseEvent) {
    const { clientX, clientY } = e;
    console.log(`x: ${clientX}, y: ${clientY}`);
  }

  // KeyboardEvent
  if (e instanceof KeyboardEvent) {
    console.log(e.code);
  }
});
  • MouseEvent, KeyboardEvent, InputEvent 등은 모두 lib.dom.d.ts에서 정의되어 있다.
  • 이벤트 핸들러는 이벤트 타입에 따라 적절한 프로퍼티(clientX, code, target.value 등)를 안전하게 사용할 수 있다.