[ TypeScript ] 유니언, 인터섹션, 이넘

·2023년 11월 14일

유니언타입(Union Types)

유니언타입이란?

유니온 타입은 타입 A 또는 타입 B 중 하나가 될 수 있는 타입을 말하며, A | B 같이 표기한다. 주로, 특정 변수가 가질 수 있는 타입을 전부 나열하는 용도로 사용된다.

function myType(types: string | number){
  console.log(types)
}

해당 코드는, OR로 정의된 stringnumber의 타입 중 어느것이라도 사용할 수 있다.
즉, 유니언 타입은 선언된 타입들 중 하나가 될 수 있는 것을 의미한다.

유니언 타입 사용의 주의점

유니온 타입인 값이 있다면, 유니언에 있는 모든 타입에 공통인 멤버들에게만 접근 가능하다
즉, 어느 타입이 오더라도 문제없을 공통 속성만 자동 완성이 가능한다.
모든 타입이 공통으로 갖고 있는 속성에만 접근할 수 있다.

interface Fruits {
  name: string;
  price: number;
}

interface Food {
  name: string;
  isKorean: boolean
}

declare function getMyFavorite() : Fruits | Food;
let wantToEat = getMyFavorite();
wantToEat.name; //호출 가능
wantToEat.price //호출 불가 (Food형식에 price가 없습니다)

서로소 유니온타입 (=식별 가능한 유니온)

겹치지 않는 타입으로 이루어진 유니온타입

interface Fruits {
  name: string;
  price: number;
}

interface Food {
  kind: string;
  isKorean: boolean
}

declare function getMyFavorite() : Fruits | Food;

위의 예시에서 두 interface의 타입의 교집합은 공집합이다.
이처럼 브랜치 간에 겹치는 부분이 없는 유니온 타입을 서로소 유니온타입이라고 한다.
서로소 유니온 타입 패턴을 사용해 서로 겹치지 않는 경우 중 하나인 타입을 표현하기 유리하다.

  • 네트워크 요청 (성공 or 실패)
  • 데이터 베이스에 특정 값이 있는가 ( 있다 or 없다 )
    -> 이와 같이 참과 거짓 외 다른 진리치가 없는 경우 사용하기에 유리하다.

특정 로직 수행하기

함수 내부에서 파라미터 타입의 종류에 따라 특정 로직을 실행하고 싶을 때 사용하는 방법

function myfav(fav : Fruits | Food ) {
  if ( 'price' in fav ) {
    ...
  }
    if( 'isKorean' in fav ) {
      ...
    }
      ```
해당 코드에서 fav가 Fruits 타입의 데이터일 때, 첫번째 if문을 사용할 수 있고, 반대의 경우도 그렇다. 

인터섹션/교차 타입 ( intersection type)

타입 2개를 하나로 합쳐서 사용할 수 있는 타입이며, 여러 가지 타입을 결합하여 하나의 단일 타입으로 만드는 경우를 말한다.
이때, 함쳐진 속성 중 하나라도 누적한다면 에러가 발생할 수 있다.

interface Fruits {
  name: string;
  price: number;
}

interface Food {
  kind: string;
  isKorean: boolean
}

declare function getMyFavorite() : Fruits & Food;

이넘

특정 값의 집합을 의미하는 데이터 타입으로 상수 집합이라고도 한다.
즉, 이넘이란 일종의 구조체를 만드는 타입 시스템이며, enum을 사용해서 열거형을 정의할 수 있는데, 열거형은 각가의 멤버를 가지고 있다.

  • 상수란? 변하지 않는 고정 값
    비슷한 성격이나 같은 범주에 있는 상수를 하나로 묶어 더 큰 단위의 상수로 만드는 것

숫자형 이넘

기본적인 추론 방식이며, 숫자 0에서부터 한개씩 늘려가며 값이 할당된다.

enum Food {
  Yogurt, 
  Salad,
  Bagel
}

console.log(Food.Yogurt)//0

이넘에 선언된 속성은 기본적으로 숫자값을 가진다.
이때 초기값은 0이고, 만약 속성의 초기값을 변경하고 싶다면 다음과 같이 선언한다.

enum Food {
  Yogurt = 2, 
  Salad,
  Bagel
}

console.log(Food.Yogurt)//2
console.log(Food.Salad)//3

문자형 이넘

이넘의 속성 값에 문자열을 연결한 이넘이다.
사실, enum타입은 주로 문자열 상수를 생성하는데 사용되며, 이를 통해 응집력있는 집합 구조체를 만들 수 있다.

enum DeliveryType{
  DELIVERY_HOLD = '배송오류...하..', 
  DELIVERY_READY = '배송 준비중',
  DELIVERING = '배송중',
  DELIVERED = '배송완료'
}

const checkDelivery = (deliveryStatus: DliveryType ) => {
  switch (deliveryType){
    case DliveryType.DELIVERY_HOLD:
    case DliveryType.DELIVERY_READY:
      return false;
    case DliveryType.DELIVERING:
    case DliveryType.DELIVERED:
      return true;
    default:
      return true;

위와 같이 해당 열거형이 가지는 모든 멤버를 값으로 받을 수 있다.
이를 통해 우리는 문자열로 지정된 타입보다 유리한 점을 가질 수 있다.
1) 타입 안정성: 해당하는 enum에 명시되지 않은 다른 문자열은 인자로 받을 수 없다.
2) 명확한 의미 전달: 어떠한 값을 다루는지 명확하다.
3) 가독성: 열거형을 통해 어떤 상태를 나타내는지 바로 확인할 수 있다.

이때 주의할 점으로는 숫자로만 이루어져 있거나, 타입스크립트가 자동으로 추론한 열거형은 안전하지 않다. 따라서 const enum을 사용하여 이를 막을 수 있다.

다양한 속성 정리

이넘은 고정의 속성 값 뿐 아니라, 다양한 값을 할당할 수 있으며, 숫자와 문자열을 섞어서 선언할 수 있다.

enum Food {
  Yogurt = 'myfav', 
  Salad,
  Rice,
  Pocke = Salad + Rice
  Bagel = "bagel".length
}

console.log(Food.Yogurt)//2
console.log(Food.Salad)//3

const 이넘

const는 이넘 앞에 붙여서 컴파일 결과물의 코드양을 줄일 수 있다.
이넘이 컴파일될 때에는 이넘 코드가 자바스크립트 코드로 변환되는데, const 이넘은 자바스크립트 객체를 생성하지 않고, 바로 속성값을 연결해줌
다만, const이넘은 속성값에 고정값만이 들어가야한다

또한, const enum으로 선언하더라도, 숫자 상수로 관리되는 열거형은 선언한 값 이외의 값을 할당하거나 방지할 수 없다. 따라서 문자열 상수 방식이 사용성에 있어서 유리하다.

const enum Food {
  Yogurt = 1, 
  Salad = 2,
  Rice = 3,
}

const myFood : Food = 50; //Food에서는 50이 없지만, 에러 발생이 나타나지 않음

cosnt enum Food {
  Yogurt = "간식", 
  Salad = "밥",
  Rice = "집밥이야!,
}
const myFood: Food = 'poke' //error
profile
new blog: https://hae0-02ni.tistory.com/

3개의 댓글

comment-user-thumbnail
2023년 11월 15일

이넘에 대해서 각각의 코드와 함께 자세히 설명해주셔서 더 이해하기 편했던 것 같아요!
특히 enum타입은 주로 문자열 상수를 생성하는데 사용되며, 이를 통해 응집력있는 집합 구조체를 만들 수 있다. 을 보고 좀 더 enum의 사용 방안에 대해 생각해볼 수 있었던 것 같아요.

아티클을 읽으면서 그럼 문자형 이넘과 interface에 문자 타입만을 가지는 key-value의 차이로는 무엇이 있을까 .. 라는 궁금증이 들어 헷갈리길래 혼자 정리해보는 시간을 가졌습니당 ,,

문자열 이넘은 값의 집합을 명시적으로 나타냄
문자열 key-value로 이루어진 인터페이스는 구조화된 데이터를 표현하는 데 사용됨!

또, 찾아보다가 좋은 아티클 있길래 공유합니다 ! 각종 enum들의 (enum , const enum, const assertion) 장단점에 따른 컨벤션 정하기에 대한 내용이에용 !
https://techblog.woowahan.com/9804/#toc-1

답글 달기
comment-user-thumbnail
2023년 11월 15일

문자형이넘 배송예시 코드 보고 enum을 왜 쓰는지 더 감을 잡았어요 ㅎㅎㅎ!! 핵심만 뽑아서 잘 정리해주셔서 복기하기 넘 좋았습니다🫶🏻

답글 달기
comment-user-thumbnail
2023년 11월 15일

제가 준비한 타입 관련 부분 이외에 이넘 부분에서 더더 많은 인사이트를 얻을 수 있었던 거 같아 정말 좋았습니다

사실 enum선언을 하기보단 constant로 상수화 하여 관리한 경험이 더 많았어서, 사용법에 대해서 익숙치 않았는데, 많은 예시코드들로 도움을 받은 거 같아요!

enum관련 공부를 하다가 사용을 지양하라는 글을 발견했는데요, 흥미로운 내용이어서 함께 첨부합니다.
https://velog.io/@sensecodevalue/Typescript-Enum-%EC%99%9C-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC%ED%95%98%EC%A3%A0
하지만 여러가지의 경우가 있으니, 가장 적절한 방식으로 알맞게 사용하는 것이 좋을 거 같아요

좋은 글 감사합니다 !! 🔥

답글 달기