타입스크립트와 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>
getElementById
→HTMLElement | null
반환querySelector
→Element | 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 등)를 안전하게 사용할 수 있다.