[TypeScript] Narrowing & Assertion (타입을 하나로 지정해주기)

keynene·2023년 7월 31일
1

TypeScript

목록 보기
3/5
post-thumbnail

"타입을 정확하게 지정하면 코드가 안전해진다."

타입스크립트(TypeScript)로 개발을 하다보면 간혹 *union type을 사용하면서 하나의 변수 혹은 함수에 타입이 한 가지로 확정되지 않는 경우가 발생하는데, 이럴 때 타입을 하나로 지정해주면서 더 정확하게 동작하도록 하는 방법이 바로 Narrowing과 Assertion이다.


*union type (연산자를 이용한 타입)

파라미터나 변수 등에 타입을 지정할 때 OR 연산자 (|)를 이용하여 여러가지 타입을 한 번에 지정할 수 있는 타입이다.

ex1) let person :string|number;
ex2) function (x :string|number)

위의 ex2와 같이 파라미터 타입을 여러가지로 정한 경우, xstring일 때와 number일 때의 함수동작이 분명 달라야 하는데 이런 경우 narrowing이나 assertion을 사용하여 타입을 하나로 지정해줄 수 있다.




Narrowing과 Assertion에 대해서

📝타입을 하나로 정해주는 Narrowing

어떠한 함수의 파라미터를 union type으로 stringnumber를 다 받아버리면 함수내부에서는 이 파라미터를 어떤타입으로 다뤄야 하는지 정해지지 않아 오류메세지를 띄운다.
그렇기 때문에 우리는 Narrowing문법으로 타입을 지정하여 함수 동작을 분리해줄 필요가 있다.


기본문법

function narrow(x :number|string){
  if (typeof x === 'number'){ // typeof : 타입 검사해주는 키워드
    // 타입이 number일 때 실행할 코드
  }
  else if (typeof x === 'string'){
    // 타입이 string 때 실행할 코드
  }
  else { // 파라미터가 number도 아니고 string도 아닌 경우 : 에러
    //에러 예외처리해주는 코드
  }
}

위와 같이 함수 사용 시 파라미터가

  1. number인 경우
  2. string인 경우
  3. 그리고 지정해둔 타입 중 그 어느것도 아닌 경우

를 분리해서 함수 동작을 다르게 하는 방법이 바로 narrowing이고,
타입스크립트는 union type설정 시 이 작업을 거의 필수적으로 해야한다.




📝타입을 표명해주는 Assertion

Narrowing과는 달리 어떠한 변수나 파라미터의 타입을 임의로 변경해버리는 방법도 존재한다.
간혹 string'123'과 같이 number와 유사한 데이터가 넘어와서 '123' + 1과 같은 연산이 불가능한 경우가 있다.
이런경우 '123'number로 변환시켜 123 + 1로 연산하고 싶은 경우 바로 이 Assertion이라는 방법을 사용한다.


기본문법

/* as 문법 */
function assert (x :number|string){
  return (x as number) + 1; // as : as 앞의 변수의 타입을 as 뒤의 타입으로 지정해주는 키워드
}

/* <>문법 */
function assert2 (x :number|string){
  return <number>x + 1; // <> : <>뒤의 변수 타입을 <>안의 타입으로 지정해주는 키워드
  						// ※ 하지만 React의 컴포넌트와 혼동할 수 있어 잘 사용하지 않음
}

🤷🏻‍♀️ 근데... 이러면 JavaScript의 Dynamic typing이랑 다를게 없지 않나?
라는 생각이 든다면 정상이다.

Assertion이라는 문법 자체가 확실히 union type 사용에서 발생하는 오류를 줄이는 역할은 수행할 수 있겠지만, 애초에 타입을 엄격히 지정해놓자는 타입스크립트의 본연의 목적 자체와 어긋나기 때문이다.

그렇기 때문에 union type과 같이 여러가지 타입을 사용해야 하는 경우 Assertion으로 강제로 타입을 변경해버리는 방법보다, 초기 설계단계에서 구체적으로 설계하고 타입에 따른 동작을 Narrowing으로 구분하는 방법이 선호된다.




📚 Narrowing VS Assertion

남의 코드를 수정해야 하는 경우가 아닌 이상 웬만하면 Narrowing을 쓰는 것이 좋다.
Assertion은 타입스크립트의 목적과도 어긋나고 불필요한 에러를 발생시킬 수 있으므로 꼭 필요한 경우가 아니라면 지양하도록 하자.

  1. 설계 단계에서 변수나 파라미터 등에 대한 초기 타입 설계를 구체적으로 하자
  2. union type을 사용해야 한다면 각 타입에 따른 동작 설계를 구체적으로 하자
  3. Narrowing 문법으로 각 타입에 따른 동작을 분명히 하자
  4. 예외처리 (union type 중 어느것도 해당되지 않는 경우의 에러 처리)를 분명히 하자
profile
keynene

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기

관련 채용 정보