다음 자바스크립트 코드는 DOM의 이벤트에 리스너로 받는 코드이다.
const listener=(e : any)=>{
const target = e.currentTarget;
const textNode = target.chilNodes[0];
console.log(textNode.getAtrribute('value');
console.log(textNode.innerText);
console.log(target.style);
}
위의 코드는 아직 아무런 문제점을 일으키지 않는다.
하지만 위의 코드를 typescript로 작성하게 되면 문제가 발생한다.
위의 코드에서 parameter 부분만 e: Event
로 바꾸어보자
const listener=(e : any)=>{
const target = e.currentTarget;
//error : Property 'chilNodes' does not exist on type 'EventTarget'.
const textNode = target.childNodes[0];
console.log(textNode.getAttribute('value');
console.log(textNode.innerText);
console.log(target.style);
}
currentTarget
이 EventTarget
인터페이스를 반환하는데, 이 인터페이스에는 Node
인터페이스에 구현되어 있는 childNodes
가 없다.HTMLElement
를 보장하여, childNodes
가 실제로 존재하는 property라고 하자const Person = Chulsoo as Huan
console.log(<Person>Jisoo.name)
any
타입 만큼 최대한 지양해야 하는 부분이다. 타입 추론이라는 강력한 typescript의 기능을 배척하기 때문이다.const listener=(e : Event)=>{
const target = e.currentTarget as Element;
const textNode = target.childlern[0] as HTMLElement;
console.log(textNode.getAttribute('value');
console.log(textNode.innerText);
console.log(target.style);
}
DOM은 아래 그림과 같은 상속 관계를 가진다.
따라서 HTMLElement
는 모든 Property를 가진다고 볼 수 있다.
하지만 무작정 HTMLElement
로 변환을 하면, 상위 인터페이스로 받아온 DOM임에도 불구하고, 하위 인터페이스에 있는 property를 사용할 지도 모른다. (typescript를 사용하는 의미가 없어짐)
따라서 MDN 사이트에서 해당 Property를 검색하여, 어떤 종류의 인터페이스에서 해당 Property가 구현되어 있는지 확인하여, 해당 인터페이스까지만 type assertion을 하는 것이 좋다.
예를 들어
getAttribute()
: Element
에 구현
innerText
: HTMLElement
에 구현