[TypeScript에서 DOM 다루기] - getElementById , createElement , appendChild 메소드와 타입

조민호·2023년 10월 27일
0

Document.getElementById

이 메서드의 정의는 다음과 같습니다

getElementById(elementId: string): HTMLElement | null;

문자열 id 요소가 전달되면 HTMLElement 또는 null이 반환됩니다.

  • 이 메서드는 가장 중요한 타입들 중 하나인 HTMLElement를 도입합니다. HTMLElement 타입은 다른 모든 요소 인터페이스의 기본 인터페이스 역할을 합니다. 예를 들면 p태그는 HTMLParagraphElement 타입이 됩니다
  • 이 메서드는 null을 반환할 수 있다는 점에 유의해야 합니다. 메서드가 실제로 지정된 요소를 찾을 수 있을지 없을지에 따라 확실한 사전 런타임이 될 수 없기 때문입니다.
    const app = document.getElementById("app");
    // document.getElementById("app")!; 해도 됨
    
    // <p></p> 요소를 생성합니다.
    const p = document.createElement("p");
    
    p.textContent = "Hello, World!";
    
    // div 요소에 p 요소를 자식 노드로 추가합니다.
    app?.appendChild(p); // optional chaining 사용
    
    // <div id="app">
    //   <p>Hello, World!</p>
    // </div>
    이런 특성 때문에 , 위의 예제에서 appendChild를 호출하기 위해 새로운 선택적 체이닝(optional chaining) 연산자가 사용되고 있습니다. 또는, non-null assertion을 사용해도 무방합니다

Document.createElement

이 메서드의 정의는 다음과 같습니다

createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];
createElement(tagName: string, options?: ElementCreationOptions): HTMLElement;

위의 정의들은 오버로드된 함수 정의들 입니다

  • 첫번째 오버로드는 기존 HTML태그에 존재하는 요소 종류들의 키값들로만 가능하도록 제네릭의 제약조건을 걸어주었습니다
    interface HTMLElementTagNameMap {
        "a": HTMLAnchorElement;
        "abbr": HTMLElement;
        "address": HTMLElement;
        "applet": HTMLAppletElement;
        "area": HTMLAreaElement;
            ...
    }
    즉, 기존에 존재하는 HTML요소들의 이름을 전달해주면 해당 HTML태그들을 만들어 주는 것입니다
  • 두 번째 오버로드는 getElementById 메서드와 매우 유사하게 작동합니다. 어떤 문자열이 전달되면 HTMLElement 표준이 반환됩니다. 이 정의는 개발자가 고유한 HTML 요소 태그를 생성할 수 있게 합니다. 예를 들면 document.createElement('xyz')는 HTML 규격에 지정된 요소가 아닌  요소를 반환합니다. ( document.getElementsByTagName를 사용해 사용자 정의 태그(custom tag) 요소와 상호작용할 수 있습니다 )

Node.appendChild

document.getElementById 함수는 HTMLElement를 반환한다 했습니다

HTMLElement 인터페이스는 Node 인터페이스를 상속한 것이고

Node 인터페이스는 Element 인터페이스를 상속한 것입니다

Element ==(확장)==> Node ==(확장)==> HTMLElement

이러한 프로토타입 확장은 모든 HTMLElements가 상위에서 표준으로 정해진 메소드의 하위 집합을 활용할 수 있게 됩니다

아래의 코드에서 p 태그를 추가하는 appendChild()메소드는 Node 인터페이스에 정의된 속성을 사용한 것입니다

const app = document.getElementById("app");
// document.getElementById("app")!; 해도 됨

// <p></p> 요소를 생성합니다.
const p = document.createElement("p");

p.textContent = "Hello, World!";

// div 요소에 p 요소를 자식 노드로 추가합니다.
app?.appendChild(p); // optional chaining 사용

// <div id="app">
//   <p>Hello, World!</p>
// </div>

그렇다면 Node 인터페이스에 정의된 속성인 appendChild() 의 메서드에 대해 알아봅시다

appendChild<T extends Node>(newChild: T): T;

제네릭으로 선언된 T는 인자로 받는 HTML요소이며 , 이 요소의 타입은

Node 인터페이스로 제한됩니다

즉, Node인터페이스에 정의된 요소타입만 새로 추가가 가능한 것입니다

profile
웰시코기발바닥

0개의 댓글