타입스크립트 타입좁히기 / 타입가드

2025. 6. 10. 16:33Coding Study/Typescript

 

타입좁히기 (Type Narrowing)

타입 내로잉이란, 조건문 등을 활용하여 넓은 타입에서 좁은 타입으로 범위를 좁히는 것을 의미한다.

 

 

value의 타입이 string | number | boolean인 경우, 각각에 대해 적절히 처리되도록 타입 좁히기

function handleValue(value: string | number | boolean) {
  // string이면 문자열 길이,
  if(typeof value ==="string"){
    return value.length
  // number면 10을 더한 값
  }else if(typeof value ==="number") {
    return value +10
  // boolean이면 반전된 값을 리턴
  }else if(typeof value ==="boolean"){
    return !value
  }
}

 

 

input이 null 또는 undefined가 아닌 문자열일 때만 길이를 반환하도록 타입을 좁히기

function getLength(input: string | null | undefined) {
  if(typeof input ==="string"){
    return input.length
  }  
}

 

 

유니언 타입으로 정의된 객체에서 kind 값을 기준으로 타입을 좁히기

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; size: number };
type Shape = Circle | Square;

function getArea(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      console.log(shape.radius);
      break;
    case "square":
      console.log(shape.size);
  }
}

 

 

함수 인자로 받은 value가 배열인지 아닌지 구분하여 타입을 좁히고, 배열이면 길이를 출력

function printLength(value: string | string[]) {
  if (Array.isArray(value)) {      //  string 도 object 이기 때문에
    console.log(value.length);      // value instanceof Object 로는 타입좁히기 안됨
  } else {
    console.log(value);
  }
}

 

 

undefined 가 아닌경우에만 대문자로 변환

function shout(name?: string) {
  if (name) {
    return name.toUpperCase();
  }
}

 

구별된 유니온 ( Discriminated Union )

  Circle type 과 Square type 의 타입을 좁히기 위한 속성인 radius 와 sideLength 라는 속성이 있다.

  하지만 타입 좁히기에서 radius 가 있는지 sideLength 가 있는지로 구분하면 직관적이지 않기 때문에

  tag나 kind 같은 속성을 추가로 작성하여 타입좁히기에 활용할 수 있다.

type Circle = {
  tag: "circle";            // 타입에 태그 달기
  radius: number;
};

type Square = {
  tag: "square";            // 타입에 태그 달기
  sideLength: number;
};

type Shape = Circle | Square;

function getArea(shape: Shape): number {
  if (shape.tag === "circle") {             // 태그로 타입 좁히기
    // 타입 좁히기 됨: shape는 Circle 타입
    return Math.PI * shape.radius ** 2;
  } else {
    // 타입 좁히기 됨: shape는 Square 타입
    return shape.sideLength ** 2;
  }
}

 

 

타입가드 연산자 / 매서드 종류

구분 연산자/메서드 설명
typeof typeof value === "string" string, number, boolean, undefined, function, object, bigint, symbol 등에 사용 가능
instanceof value instanceof ClassName 클래스 인스턴스인지 판별
in "prop" in value 해당 속성이 객체에 존재하는지 판별
truthy 체크 if (value) null, undefined, false, 0, "" 등을 걸러냄
배열 판별 Array.isArray(value) 배열인지 확인 (value is any[]로 좁혀짐)
typeof NaN 체크 Number.isNaN(value) NaN 값인지 확인
typeof 정수 판별 Number.isInteger(value) 정수 여부 판별 가능

 

사용자 정의 타입 가드

type Fish = { swim: () => void };
type Bird = { fly: () => void };

type Animal = Fish | Bird

//사용자 정의 타입 가드 방법 1                            // 함수가 return 하는 값이 true 일때
function isFish(animal: Animal): animal is Fish {   // animal 을 Fish type으로 반환 한다.
  return "swim" in animal;                          
}                                                  


//사용자 정의 타입 가드 방법 2
//function isFish(animal: Animal): animal is Fish {
//  return (animal as Fish).swim !== undefined
//}

function move(animal: Fish | Bird) {
  if (isFish(animal)) {                // isFish(animal) 이 true 면 Fish type 이 보장된다.
    animal.swim();
  } else {
    animal.fly();
  }
}}