[TypeScript] Narrowing

이어진·2025년 1월 21일
0

타입스크립트

목록 보기
2/5
post-thumbnail

내로내로내로내로

Narrowing이 뭔데요...내로내로내로잉

처음 선언한 것보다 더 구체적인 유형으로 구체화하는 프로세스

라는데요 어렵죠. 그냥 분기 태워서 범위를 좁힌다는 뜻입니다. 아래의 코드에서는 Fish인지 Bird인지의 범위를 좁힌다는 게 되겠네요.

Narrowing을 써야할 때

type Fish = { swim: string }
type Bird = { fly: string }
function narrowing(animal: Fish | Bird) {...}

이런 코드가 있다고 해봅시다. 나는 animal.swim을 빼서 쓰고 싶은데... 라는 생각 할 수 있지 않겠습니까.

근데 저기다 대고 냅다 animal.swim 하면 타입스크립트가 혼내줍니다.

아직 Fish인지, Bird인지 모르는데? 니가 뭔데 아직 모르는 걸 갖다 써 안돼 돌아가! 하고요.

그래서 필요한게 Narrowing이라는 겁니다.

typeof

기본적인 방법인 typeof는 이럴때 씁니다.

function narrowing(a: string | undefined) {
  if (typeof a === 'string') {...}
}

astring이 들어왔을 때 if문을 태우는 방식입니다. typeof a를 하면 그 자리에 string이 남겠죠? 그걸 가지고 비교합니다.

typeof가 판단가능한 애들

typeof만으로는 안 돼요

위의 코드를 그대로 가져와서 Narrowing의 대표 방식 중 하나인 typeof로 분기를 태워봅시다.

type Fish = { swim: string }
type Bird = { fly: string }
function narrowing(animal: Fish | Bird) {
  if (typeof animal === Fish) {
    ...
  } else {
    ...
  }
}

혹시 이렇게 생각하셨나요.

그라믄 안 됩니다. 지금 Fish에 들어있는게 뭐죠?
{ swim: string }이라는 Object입니다. 그럼 typeof animal을 한 자리에는 우리가 생각한 것처럼 Fish가 아니라 object가 남습니다. 그럼 당연히 옆에 비교한 타입과는 다르겠죠.

이렇게 typeof 연산자는

1. number
2. string
3. boolean
4. object
5. bigint
6. function
7. symbol

얘네 같은 애들만 판단이 가능합니다.

in

이럴 때는 in 키워드 갖다 쓰시면 됩니다.

각각의 타입이 가진 속성이 서로 다를 때

<속성명> in <오브젝트 자료>

저희는 Fish-오브젝트 자료에서 swim-속성명 을 빼고 싶은거니까 이렇게 작성할 수 있겠네요.

type Fish = { swim: string }
type Bird = { fly: string }
function narrowing(animal: Fish | Bird) {
  if ('swim' in Fish) {
    return animal.swim
  }
  return animal.fly
}

instanceof

in 키워드와 유사하게 instanceof 라는 연산자가 있습니다. 이건 class에서 사용합니다.

<오브젝트> instanceof <부모class>

어떻게 동작하냐면 object 두 개가 비슷하면 부모 class가 누군지 물어봐서 narrowing이 가능하게 됩니다.

어떤 클래스로부터 new 키워드로 생성된 object들이 있습니다.
그런 object 들은 instanceof 키워드를 붙여서 부모 클래스를 검사할 수 있습니다.

대표적으로 Date를 한 번 볼까요.

let date = new Date();
if (date instanceof Date){
  console.log('내 자식 맞아요!')
}

literal type으로 narrowing

근데 아래 코드를 한 번 볼까요.

type Car = {
  wheel : '4개',
  color: string
}
type Bike = {
  wheel : '2개',
  color: string
}
function narrowing(mobility: Car | Bike) {
  ...
}

여기선 어떻게 narrowing을 해야할까요?
1. in을 쓰기엔 속성이 같은데요.
2. instanceof는 클래스에서 사용한다면서요? 부모 class도 없는데요.

object 타입이 둘 다 비슷하게 생겼는데요❗❗

타입을 한 번 잘 보십쇼. 전글에서 언급했던 literal type이 보이지 않습니까.

비슷한 object 타입일 경우 literal type을 강제로 만들어두면 나중에 도움이 됩니다. object가 ⭐유니크⭐해지거든요.

Carwheel에는 무조건 '4개'라는 타입만 들어올 수 있습니다. Bike도 마찬가지구요.

그럼 이렇게도 narrowing 할 수 있습니다.

function narrowing(mobility: Car | Bike) {
  if (mobility.wheel === '4개') {
    console.log('차 색: ' + mobility.color)
  } else {
    console.log('바이크 색: ' + mobility.color)
  }
}
profile
코딩하는 말하는 감자

0개의 댓글