HTMLElement 은 모든 HTML요소 타입의 최상위 타입이다
그래서 언뜻 보면 , 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속성을 예로들면**
그러므로 TS에서는 input태그에 대해 .value 속성을 사용하기 위해선
타입을 HTMLElement 대신 , HTMLInputElement로 해야 합니다
// HTML
<input type="text" id="username" placeholder="Enter username" />
// TS
// Non-null Assertion 필수
const username:HTMLElement = document.getElementById('username')!;
console.log((username as HTMLInputElement).value) // 해당 input태그의 내용이 출력
이렇게 하면 null값도 자동으로 방어가 되고 , 바로 .value속성을 사용할 수 있으므로 보다 코드가 간결해 집니다
// HTML
<input type="text" id="username" placeholder="Enter username" />
// TS
const username:HTMLInputElement= document.getElementById('username') as HTMLInputElement;
console.log(username.value) // 해당 input태그의 내용이 출력
getElementById() 같은 메소드로 DOM요소를 불러올때 null값을 막아줘야 하는데 굳이 non-null assertion이나 다른 방법으로 null을 막기보다는 , 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가지가 있다
HTMLElement타입의 요소에다가 type assertion을 사용
// username은 HTMLElement
const username = document.getElementById('username') as HTMLElement;
// checkLength의 인자로 username을 넘겨줌
checkLength(username **as HTMLInputElement**);
// checkLength의 인자는 HTMLInputElement 타입
function checkLength(input:HTMLInputElement) { ... }
// username은 HTMLElement
const username = document.getElementById('username') as HTMLElement;
// checkLength의 인자로 username을 넘겨줌
checkLength(username);
// checkLength의 인자는 HTMLElement 타입
function checkLength(input:**HTMLElement**) {
// 사용하게 될 때 type assertion을 해서 사
(input **as HTMLInputElement**)
}
아예 처음에 DOM객체를 가져올때부터 type assertion으로 HTMLInputElement으로 선언해주기
// username은 **HTMLInputElement 타입**
const username = document.getElementById('username') **as HTMLInputElement;**
// checkLength의 인자로 username을 넘겨줌
checkLength(username);
// checkLength의 인자는 HTMLInputElement 타입
function checkLength(input:HTMLInputElement) {...}