[TS] 타입 단언 Type assertion & 타입 가드 Type Guard

김다빈·2023년 9월 2일

타입스크립트

목록 보기
5/13
post-thumbnail

📌 타입 단언 Type assertion

타입스크립트가 추론하지 못하는 타입을 개발자가 직접 명시해주는 문법

개발자가 컴파일러에 내가 너보다 타입에 대해 더 잘 알고있으니 의심하지 말라고 하는 것

var foo = {};
foo.bar = 123; //ERROR
foo.bas = 'hello'; //ERROR

객체에 점표기법을 사용해서 속성과 값을 추가하려고 하는데 오류가 발생한다.
왜냐하면 컴파일러는 foo가 속성이 없는 객체라고 가정하기 때문에
만약 처음부터 속성이 있는 객체라면 bar와 bas 속성의 타입을 정해주었어야 함.

이런 경우에 타입 단언을 사용할 수 있다.

interface FOO {
  bar: number;
  bas: string;
}

var foo = {} as FOO;
foo.bar = 123; //정상 작동!
foo.bas = 'hello'; //정상 작동!

✴️ 예시 1

const bodyEl = document.querySelector('body')
bodyEl.innerText = 'Hello'; //ERROR

왜 오류가 발생할까?

힌트를 보면 bodyEl의 타입이 HTMLBODYElement 일뿐만아니라 null 일 수도 있다!

HTML 문서에 body 태그가 분명히 있음에도 불구하고 null 일수도 있다고 추론하는 이유는 뭘까?
➡️ 개발자는 HTML 문서에 body 태그가 있다는 사실을 확실하게 알고 있지만 타입스크립트는 그걸 알 수가 없다. 그래서 body요소가 null일 수도 있다고 추론한다.
그리고 만약 body태그가 없어서 bodyElnull 일 경우 innerText를 사용할 수도 없다.

이 문제를 해결하기 위한 방법이 3가지 있다.

1. 타입 단언

as HTMLBODYElement 를 붙여 타입 단언

const bodyEl = document.querySelector('body') as HTMLBODYElement
bodyEl.innerText = 'Hello';

2. ! not null 타입 단언

! : exclamation / bang operator 느낌표 연산자
! 를 붙여 undefinednull이 절대 아니라고 타입 단언

const bodyEl1 = document.querySelector('body')
bodyEl1!.innerText = 'Hello';

3. 타입 가드

const bodyEl2 = document.querySelector('body')
if (bodyEl2) {
  bodyEl2.innerText = 'Hello';
}

✴️ 예시 2

function func(arg: string | null) {
  return arg.toLowerCase(); //ERROR
}

왜 오류가 발생할까?

함수의 매개변수인 arg의 타입이 string 또는 null이 될 수 있는데
만약 null이라면 toLowerCase() 메소드를 사용할 수 없다.
따라서 arg가 string일 때만 arg.toLowerCase()를 리턴하도록 코드를 작성해야한다.

가장 먼저 생각나는 방법은 타입 단언

function func(arg: string | null) {
  return (arg as string).toLowerCase();
}

이렇게 하면 해결 될 것같았는데 또 오류남!

이유는 타입 에러만 해결해줬을 뿐이지 만약 arg 값으로 null을 넣으면 얘는 여전히 null.toLowerCase() 를 수행해야 함 (다시 원점으로 돌아옴)

그러면 시도해볼 수 있는 방법이 타입 가드!

function func(arg: string | null) {
  if (arg) {
    return (arg as string).toLowerCase();
  }
}

arg가 값이 있을 때만 .toLowerCase()을 수행할 수 있도록 수정

profile
Hello, World

0개의 댓글