본문 바로가기
배움 기록/TypeScript

[TypeScript] Narrowing 정리 (typeof, instanceof, as...)

by dygreen 2023. 1. 29.
Type 'string | number' is not assignable to type 'number'.
만약 위와 같은 에러 메세지를 본 적이 있다면, 이는 Type Narrowing이 필요하여 발생한 에러입니다.

 

 

📌 Type Narrowing ?

: (위의 에러 메세지를 예로 들면) string | number 같은 union type에는 일반적으로 조작을 못하게 막아놨기 때문에

  1. 타입을 하나로 Narrowing(=좁히다) 해주거나
  2. 타입을 Assertion(=선언) 해주는 것이 필요하다.

 

 

Narrowing으로 판정해주는 문법들 (대표 3개)

  1. typeof 변수
  2. 속성명 in 오브젝트 자료
  3. 오브젝트 instanceof 부모 class

 

 

📌 typeof 연산자

: 타입을 하나로 지정해주려면 if문 등으로 해줄 수 있다.

function 함수(x: number | string) {
  if (typeof x === 'string') {
    return x + '1'
  } else {
    return x + 1
  }
}

→ 여기서 주의할 점은 typeof 연산자를 쓸 때 type은 '' 로 감싸서 string 형태를 띄어야 한다.

 

위 함수를 해석해 보면 다음과 같다.

" x가 'string' 타입일 경우 x에 '1'을 더해주세요 "

" x가 'string' 타입이 아닐 경우(='number'타입) x에 1을 더해주세요"

 

 

📌 속성명 in 오브젝트 자료

: in 키워드로 Narrowing을 해줄 수 있다.

type Fish = { swim: string }
type Bird = { fly: string }

function check2(animal: Fish | Bird) {
  if ('swim' in animal) { // swim이라는 속성이 animal이라는 오브젝트에 있는지
    animal.swim
  }
}

→ 여기서 주의할 점은 union type이 서로 다른 속성을 가지고 있어야 in 키워드를 사용할 수 있다.

 

만약, Fish와 Bird 둘 다 'swim'이라는 속성을 가지고 있으면 Narrowing이 불가능한 것!

 

 

📌 오브젝트 instanceof 부모 class

: 만약 class로부터 생산된 object라면 instanceof 연산자로 Narrowing이 가능하다.

let 날짜 = new Date()
if (날짜 instanceof Date) { // 왼쪽 오브젝트(=날짜)가 오른쪽에 있는 class(=Date)의 자식인지
  console.log('today')
}

 

 


Type Narrowing 외에 Type Assertion이라는 방법도 있다

 

📌 Type Assertion ?

: Type을 잠깐 덮어쓰는 개념이다. *자주 사용하지 말기

  • Narrowing을 할 때 사용 (여러 개의 타입을 하나로 확정 지을 때 사용)
  • 실제로 타입을 바꿔주는 것이 아니기 때문에, 무슨 타입이 들어올지 100% 확실할 때 사용하는 것이 좋음
function 함수(x: number | string) {
  return (x as number) + 1 // 왼쪽에 있는 변수를 number로 덮어씌워라
}

console.log(함수('123')) // 버그로 캐치 못 함(=주장만 하는거지 실제로 타입을 바꿔주지는 않음)

 

 

[번외] null & undefined 체크하는 방법

1) 변수 != null

if (변수 != null)

→ null, undefined 두 개를 동시에 거를 수 있다.

 

 

 

2) && 연산자 사용

function 함수(a: string | undefined) {
  if (a && typeof a === 'string') {
    // a가 undefined이면 if문 실행 X
    // a가 string이면 if문 실행 O
  }
}

 && 기호로 비교할 때 true와 false를 넣는게 아니라 자료형을 넣으면,

&& 사이에서 처음 등장하는 falsy 값을 찾아주고, 그게 아니면 마지막 값을 남겨준다.

(*falsy 값 = false와 유사한 기능을 하는 null, undefined, NaN 이런 값들을 의미)

 

 


참고 : 코딩애플 강의

 

728x90

댓글