그래서 언뜻 보면 , input 태그의 경우 HTMLElement 를 사용하지 않고
굳이 HTMLInputElement로 타입을 구분지어서 사용할 필요가 있나 싶기도 했다
그렇지만 반드시 구분을 지어야 하며 차이가 존재한다
우리가 getElementById()로 HTML태그를 불러올 때 리턴받는 DOM객체의 타입은 HTMLElement이다
lib.dom.d.ts
/**
* Returns a reference to the first object with the specified value of the ID attribute.
* @param elementId String that specifies the ID value.
*/
getElementById(elementId: string): HTMLElement | null;
이때 , HTMLElement타입은 DOM객체의 기본타입이고
HTMLInputElement 같은 타입들은 HTMLElement타입을 상속한다
그리고 이때 , input태그의 값에 접근할 수 있는 .value속성을 예로들면
// HTML
<input type="text" id="username" placeholder="Enter username" />
// TS
const username:HTMLElement = document.getElementById('username')!;
console.log((username as HTMLInputElement).value) // 해당 input태그의 내용이 출력
getElementById가 리턴하는 DOM객체의 타입은 HTMLElement타입
이므로 타입을 HTMLElement로 사용하고
사용할 때 , HTMLInputElement로 type assertion을 진행해야 한다
// username은 HTMLElement
const username = document.getElementById('username') as HTMLElement;
// checkLength의 인자로 username을 넘겨줌
checkLength(username); // 에러 발생
// checkLength의 인자는 HTMLInputElement 타입
function checkLength(input:HTMLInputElement) { ... }
처음에는 HTMLElement가 가장 상위 개념이므로 HTMLInputElement
타입에도 사용이 가능할 줄 알았다
그렇지만 위의 방법처럼 HTMLInputElement 에다가 HTMLElement를 사용하게 될 경우 아래와 같은 에러가 발생한다
'HTMLElement' 형식의 인수는 'HTMLInputElement' 형식의 매개 변수에 할당될 수 없습니다.
'HTMLElement' 형식에 'HTMLInputElement' 형식의 accept, align, alt, autocomplete 외 53개 속성이 없습니다.
이를 해결 하는 방법은 2가지가 있다
// username은 HTMLElement
const username = document.getElementById('username') as HTMLElement;
// checkLength의 인자로 username을 넘겨줌
checkLength(username **as HTMLInputElement**);
// checkLength의 인자는 HTMLInputElement 타입
function checkLength(input:HTMLInputElement) { ... }
넘겨줄때 HTMLElement로 넘겨주고
받아서 사용할때 HTMLInputElement 으로 type assertion을 해서 사용하기
// username은 HTMLElement
const username = document.getElementById('username') as HTMLElement;
// checkLength의 인자로 username을 넘겨줌
checkLength(username);
// checkLength의 인자는 HTMLElement 타입
function checkLength(input:**HTMLElement**) {
// 사용하게 될 때 type assertion을 해서 사
(input **as HTMLInputElement**)
}