TypeScript에 대한 간단한 정리 - 04. 타입 및 할당 단언(Assertions)

2024. 12. 16. 19:43Programming Language/Node.js

타입의 단언(Assertion)이란 사용자가 이 값은 내가 특정 타입임을 확신한다라고 컴파일러에게 알려주는 방법이다.

이건 컴파일러가 추론한 타입이나 지정한 타입과는 관계 없이 사용자가 원하는 타입으로 강제로 인식하게 하는 역할을 하한다.

이는 자바스크립트의 런타입에는 영향을 미치지 않고 컴파일 단계에서만 작동한다.

 

타입단언의 특징은 

  • 컴파일러의 타입 추론을 덮어쓴다 - 컴파일러가 추론한 결과를 무시하고 사용자가 직접 타입을 지정할 수 있다
  • 런타임 동작에 영향을 주지않는다 - 컴파일에서만 영향을 주고 런타임 코드에는 반영되지 않기에 런타임에서 오류를 발생시킬 여지가 있다.

타입 단언을 사용하는 방식은 크게 두가지 표기법이 있는데 

 

as 키워드를 사용

변수명 as 타입

으로 타입 단언을 사용할 수 있다.

let value: unknown = "Hello, TypeScript!";

unknown 타입의 value라는 변수에 문자열을 넣어준 다음에 (타입이 지정되지 않았음, unknown임)

let strLength: number = (value as string).length;

value를 as 키워드를 통해서 string으로 타입을 단언해주면 .length메서드의 사용이 가능해지면서 number타입에 strLength라는 변수에 문자열의 길이를 넣어줄 수 있게 된다.

 

<>(꺽쇠) 표기법(JSX에서는 사용불가)

<타입>변수명

과 같이 타입단언을 사용할 수 있다.

let value: unknown = "Hello, TypeScript!";

동일하게 unknown 타입의 value에 문자열을 넣어주고 

let strLength: number = (<string>value).length;

이렇게 value앞에 <>를 사용해서 타입을 넣어주면 해당 string 타입으로 변경해준다.

 

이 타입 단언의 경우는 사용자가 해당 값에 대한 타입이 확실할때 사용한다.

컴파일러는 값을 구체적으로 추론하지 못할때 개발자가 값에 대한 타입을 명시적으로 단언해줌으로써 컴파일 에러를 막는다

let someValue: unknown = "This is a string";

이렇게 문자열이 unknown타입일때는 length 속성을사용할때 컴파일에러를 발생시킨다.

let strLength: number = someValu.length; //==> 컴파일 에러 발생

이때 타입 단언을 사용해서 문자열임을 명시해주면 length 속성의 사용이 가능해진다

let strLength: number = (someValue as string).length;

 

또 DOM 요소를 다룰 때 타입스크립트가 기본적으로 HTMLElement 나 null 타입을 추론하게 되는데 null을 방지하기 위해서 특정 요소 타입임을 단언 하는 경우도 있다.

const inputElement = document.getElementById("username") as HTMLInputElement;

이렇게 무조건 HTMLInputElement라고 단언해주면 

inputElement.value = "TypeScript";

DOM 요소의 value 속성을 안전하게 사용할 수 있다(컴파일 에러를 발생시키지 않음)

 

실제 예시를 하나 확인해보면 

이렇게 html파일에 무조건 존재할 만한 태그인 body 태그를 querySelector로 불러 와서 textContent라는 속성을 사용하려고 하는데 보면 element에 null이 들어가지 않을 것임에도 불구하고 타입스크립트는 body라는것이 없을 수 도 있다고 걱정을 한다.

이럴때 타입 단언을 사용하면 되는데

이렇게 as 키워드를 사용해서 HTMLBodyElement로 타입을 단언해주던가 

<>꺽쇠를 사용해서 타입을 단언해줄 수 도 있다.

 

여기서 추가적으로 !를 사용하면 non-null 단언을 해줄 수 있는데 이는 해당 값은 절대 null이 아니라고 단언해주는 것이다.

방법은 

이렇게 에러가 나오는 변수의 끝에(. 연산자 앞에) ! 를 붙여주면 

이 값은 null 로 들어올 일이 없다고 단언할 수 있다.

 

그런데 만약 무조건 존재하는 body 태그가 아니라 진짜 태그가 없어서 DOM요소를 못가져왔다면 컴파일 시점에는 문제가 없으나 런타임 시점에서 에러가 발생할 것이다.

이렇게 존재하지 않는 id가 test인 div태그를 가져오려고 시도 하고 DOM요소의 속성인 innerHTML을 가져와 출력하려고 한다고 해보자.

그러면 분명 element에 innerHTML이 없다고 에러를 출력할 것이다.

이렇게 단언해준 다음에 서버를 가보면

이렇게 null에 해당 속성은 없다 라고 에러가 발생한다.

이런 경우에는 타입 가드라는 방법을 사용하는데 별건 없고 그냥 if 문법을 사용해서 해당 타입이 안전한지를 체크해주는 방법이다.

이렇게 if 문을 통해서 조건문으로 element가 null임을 체크해주면 타입 단언을 사용하지 않아도 컴파일 에러가 생기지 않는다.

 

 

추가로 하나의 예시를 더 보자면 

이렇게 문자나 숫자를 하나 매개변수로 받고 두번째 인자로 이 값이 숫자인지를 체크하는 boolean 타입의 값을 받는 함수가 존재할때 이 함수의 경우는 첫번째 인자가 어떤 것인지에 따라서 사용하는 메서드가 달라지게 된다.

이런 경우에도 타입 단언을 사용해서 받을 수 있는데 이때는 받을 수 있는 값이 null이란 조건이 없기 때문에 non-null 단언 연산자인 !는 사용이 불가능하다.

 

그렇기 때문에 이 값의 경우는 타입 단언만이 사용이 가능하다.

 

 

그리고 여기서 추가적으로 할당 단언이라는 개념을 볼 텐데 자바스크립트에서는 어떤 값에 아무값도 할당되어 있지 않으면 undefined가 나오면서 에러를 발생시키지는 않는다.

 

타입 스크립트의 경우는 이런 것에 대해서 엄격하기 때문에 

이렇게 할당 이전에 사용하면 에러를 발생시킨다.

이때 이 변수는 할당이 무조건 되어 있다고 단언해주는데 이때는 변수를 선언하는 라인에서 타입을 나타내기위한 : 연산자의 앞에 !를 붙여준다.

이렇게 사용하는게 할당 단언이다.

이러고 출력된 결과를 확인하면

동일하게 undefined를 출력하는 모습을 볼 수 있다.