Frontend/TypeScript

[TypeScript] 타입 단언 Type Assertion

Rayched 2023. 10. 6. 17:07
1. 개요
 ① 문제 발생 (ts2339: Property does not exist on type)
 문제 해결과정 1 (변수 SearchInput에 저장되는 DOM 객체의 타입을 HTMLElement로 단언)

  문제 해결과정 2 (변수 SearchInput에 저장되는 DOM 객체의 타입을 HTMLInputElement로 수정)
2. 타입 단언 (Type Assertion0)
3. Reference

1. 개요

① 문제 발생 (ts2339: Property does not exist on type)

 

'나만의 크롬 시작화면'의 검색창을 구현하다가 아래와 같은 Error를 보게 되었다.

const SearchInput = document.getElementById("Search_Input");

const ShowSearchResult = () => {
    if(!SearchInput) return;
    let SearchWord = SearchInput.value; //error part

    window.location.href=`https://www.google.com/search?q=${SearchWord}`;
    SearchWord = "";
};

Property 'value' does not exist on type 'HTMLElement' (ts2339)
=> 'HTMLElement' 객체 내부에 'value'라는 Property가 존재하지 않는다.

② 문제 해결과정 1 (변수 SearchInput에 저장되는 DOM 객체의 타입을 HTMLElement로 단언)

 

에러 메시지를 파파고의 힘을 빌려서 해석해 보고, 문제를 해결하기 위해서 바로 구글링 시작

검색어는 'ts2339', 'Property does not exist on type' 두 가지로 검색을 해봤다.

다른 개발자 분들이 개인 블로그에 정리해 둔 글들을 읽어보니 타입 단언을 통해서 해결할 수 있다고 한다.

(타입 단언에 대해서는 다음 챕터에서 다루도록 하겠다.)

 

변수 SearchInput에 할당되는 DOM 객체의 타입을 HTMLElement로 단언하는 코드를

아래와 같이 작성하고 확인해 봤지만 Error가 해결되지는 않았다.

const SearchInput = document.getElementById("Search_Input") as HTMLElement;

const ShowSearchResult = () => {
    if(!SearchInput) return;
    let SearchWord = SearchInput.value; //error part

    window.location.href=`https://www.google.com/search?q=${SearchWord}`;
    SearchWord = "";
};

SearchInput의 타입을 HTMLElement로 단언했지만 error는 해결되지 않았다.


③ 문제 해결과정 2 (변수 SearchInput에 저장되는 DOM 객체의 타입을 HTMLInputElement로 수정)

 

SearchInput의 타입을 HTMLElement로 단언해 봤지만 문제는 해결되지 않았다.

다른 해결법을 찾기 위해서 구글링을 해봐도 마땅한 방법을 찾지 못해서 절망하고 있다가

혹시나 해서 타입을 HTMLElement에서 HTMLInputElement로 수정해 보니 Error가 해결되었다.

const SearchInput = document.getElementById("Search_Input") as HTMLInputElement;

const ShowSearchResult = () => {
    if(!SearchInput) return;
    let SearchWord = SearchInput.value; //error part

    window.location.href=`https://www.google.com/search?q=${SearchWord}`;
    SearchWord = "";
};

프로젝트 코드를 작성할 당시에는 편의점 알바 출근할 시간이 가까워져서

어떤 원리로 해결됐는지 바로 파악하지 않고 일단 미뤄두다가 현재 글을 쓰는 시점에서

왜 타입을 HTMLInputElement로 수정했을 때 Error가 해결됐는지 궁금해져서 구글링을 해봤고

ts2339 Error가 해결된 이유를 알게 됐으며, 그 이유를 바로 아래 정리해 뒀다.


HTMLInputElement (Web APIs / MDN)

출저: HTMLInputElement (Web APIs / MDN)

HTMLElement HTMLInputElement 상위 요소이고

HTMLInputElement는 HTMLElement의 Property와 method를 상속받은 하위 요소이다.

 

이것만 보면 Input 요소는 HTMLElement로 타입을 지정해도 문제가 없어야 하지만

실제로 Input 요소의 타입을 HTMLElement로 단언을 했을 때

'value' Property를 참조할 수 없는 Error가 발생했었다.

 

이는 'value'라는 Property가 상위 요소인 HTMLElement에선 정의되지 않은

하위 요소인 HTMLInputElement에서만 정의된 Property이기 때문에 발생한 문제로

SearchInput에 저장되는 DOM 객체를 HTMLInputElement로 타입 단언을 했을 때

ts2339 Error(Property 'value' does not exist on type 'HTMLElement')가 해결된 것을 통해서 증명할 수 있다.

 

실제로 HTMLElement 문서를 확인해 보면  'value' Property에 대한 내용이 없지만

HTMLInputElement에만 'value' Property에 관한 내용이 있는 것을 통해서

HTMLElement 객체에서 'value'라는 Key 값을 가진 Property가 정의되지 않았다는 것을 알 수 있다.

HTMLElement (Input events) / HTMLInputElement (value)

 


2. 타입 단언 (Type Assertion)

Assert"주장하다.", "확고히 하다"라는 의미를 가진 단어이고

국어사전에 따르면 '단언'이라는 단어는 "주저하지 않고 딱 잘라 말하다."라는 의미를 가지고 있다.

 

이를 통해서 타입 단언 (Type Assertion)의 의미에 대해 나름대로 추론해 보자면

"이 타입에 대해 내가 정의한 게 맞다는 주장을 하다."라는 뜻으로 해석할 수 있을 것 같다.

여기서 타입은 Data Type, 자료형이고, 주장을 하는 대상은 TypeScript 컴파일러다.

 

이걸 모두 참고해서, 타입 단언에 대해 정의를 내리자면 다음과 같다.

"개발자가 해당 타입에 대해 TypeScript 컴파일러보다 강한 확신을 가지고 있을 때 사용되는 타입지정 방식"

 

타입 단언은 다른 언어의 Type Casting (형변환)과 비슷한 개념이지만

컴파일 시 특별히 타입을 확인하지 않고, 데이터의 구조도 특별히 신경 쓰지 않는다는 차이점이 존재한다.

 

타입 단언은 'as' 키워드를 통해서 할 수 있으며, 아래와 같은 형식으로 작성한다.

변수 as Type

//타입 단언 예제

const name: string = "홍길동";
//타입 선언 방식
//name 변수의 타입을 string으로 선언

const name = "홍길동" as string;
//name 변수가 string이라고 명시

타입 단언은 개발자가 TypeScript 컴파일러보다 해당 Type에 대해 잘 알고 있거나

아니면 JavaScript 기반 프로젝트에 점진적으로 TypeScript를 적용하는 경우에 주로 활용된다.


3. Reference

역시 JavaScript 기반 프로젝트에 TypeScript를 적용시키다보니 여러가지 크고 작은 벽에 부딫힐 일이 많아진 것 같다.

예전에 JavaScript로 코드를 짤때와는 사뭇 다른 풍경이다.

그래도 아무 생각없이 강의에서 나온 소스코드를 그대로 따라칠 때보다는

TypeScript를 적용시키면서 발생하는 크고 작은 문제들을 해결하면서 배워나가는 게 많다는 것을 생각하면

역시 프로젝트에 TypeScript를 적용하기로 결정한 것은 잘한 일인 것 같다는 생각이 든다.

참고한 문서 목록

[에러 일지] TypeScript - Type Assertion으로 'Property does not exist...' - ts(2339) 오류 해결하기 (velog)
타입 단언 (타입스크립트 핸드북)
HTMLInputElement (Web APIs | MDN)