ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 대수 타입
    TypeScript 2023. 6. 11. 21:34

     

     


     

     

    1.대수 타입(Algebraic Types)이란?

    대수 타입이란 여러 타입을 조합하여 새로운 타입을 만들 수 있는 기능을 말한다.

    종류로는 유니온 타입(Union Types),인터섹션 타입(Intersection Types)이 있다.

    타입을 집합으로 생각할 때, 집합 간의 연산을 표현하는 방식으로 이해할 수 있다.

    유니온 타입은 합집합에 해당하고 인터섹션 타입은 교집합에 해당한다.

     

    1️⃣인터섹션 타입-교집합

    인터섹션 타입은 &을 이용해서 교집합 타입을 만든다. 이러한 교집합 타입은 객체타입에서 많이 사용된다.

    일반 원시값으로 사용하면 서로 교집합 하는 부분이 없기 때문에 never를 반환하게 된다. 

     

    👉🏻원시 타입

    let variable : number & string

    👉🏻객체 타입

    Type Dog = {
    	name:string;
    	howling:boolean;
    }
    Type Cat = {
    	name:string;
    	grooming:boolean;
    }
    
    type Intersection = Dog & Cat
    
    let intersection:Intersection = {
      name:'개냥이',
      howling:true,
      grooming:true,
    }

    교집합인 name,howling,grooming의 속성을 만족하는 값만 들어올 수 있게 된다. 

     

    2️⃣유니온 타입-합집합

    여러 개의 타입을 하나의 타입으로 결합하는 방법이다. 

    기호(|)를 사용하여 타입들을 나열해 표현한다. 

    👉🏻기본 타입

    let a : string | number;
    a = 1;  //ok!
    a = "hello"; //ok!

    string과 number 모두를 포함하기 때문에 둘 다 사용가능.

     

    👉🏻객체 타입

    type Dog = {
      name:string;
      howling:boolean
    }
    type Cat = {
      name:string;
      grooming:boolean;
    }
    type Mixed = Dog | Cat 
    
    const cat:Mixed = {
    	name:"고양이",
    	grooming:true,
    }
    const dog:Mixed = {
    	name:"강아지",
    	howling:true,
    }
    const dogCat:Mixed = {
    	name:"개냥이",
    	howling:true,
    	grooming:true
    }

    

    이렇게 {name,howling}, {name,grooming} , {name,howling,grooming}  

    교집합 까지 포함한 세 가지의 형식을 사용할 수 있는 것이다.

     

    2.서로소 유니온 타입(disjoint union type)

    서로 중복되지 않는 타입들의 합집합을 표현하는 방법이다. 각각의 타입은 서로 독립적이며, 

    공통된 속성이 없는 타입들을 조합하여 새로운 타입을 만들 수 있다.
    이런 서로소 유니온 타입에서는 구별된 유니온(Discriminated Union)이라는 것을 사용할 수 있다.

    이것은 공통된 속성을 사용하여 각각의 타입을 식별할 수 있도록 하여 가독성와 유지보수성을 향상시킨다.

    type Dog = {
      name: string;
      howling: boolean;
    };
    
    type Cat = {
      name: string;
      grooming: boolean;
    };
    
    type Bird = {
      name: string;
      wing: boolean;
    };
    
    type Pet = Dog | Cat | Bird;

    이러한 서로소 유니온 타입이 있다.

    function animal(pet: Pet) {
      if ("howling" in pet) {
        console.log(`${pet.name}는 하울링을 합니다.`);
      } else if ("grooming" in pet) {
        console.log(`${pet.name}는 그루밍을 합니다.`);
      } else if ("wing" in pet) {
        console.log(`${pet.name}는 날개가 있습니다.`);
      }
    }

    매개 변수로 들어오는 pet에 따라 출력이 변경되도록 하기 위해 타입가드를 사용하여 타입을 좁혀줄 수 있다.

    이렇게 동작하는것에는 문제는 없지만 구별된 유니온을 사용하여 가독성을 높일 수 있다.

    type Dog = {
      type: "강아지";
      ...
    };
    
    type Cat = {
      type: "고양이";
      ...
    };
    
    type Bird = {
      type: "새";
      ...
    };

    이렇게 공통의 속성인 type을 추가하고 이를 문자열 리터럴로 정의해준다.

    이것을 이용해서 다시 타입가드의 가독성을 높일 수 있다.

    function animal(pet: Pet) {
      if (pet.type === "강아지") {
        console.log(`${pet.name}는 하울링을 합니다.`);
      } else if (pet.type === "고양이") {
        console.log(`${pet.name}는 그루밍을 합니다.`);
      } else if (pet.type === "새") {
        console.log(`${pet.name}는 날개가 있습니다.`);
      }
    }

    또는 switch문을 사용해서 만들 수 있다.

    function animal(pet: Pet) {
      switch(pet.type){
        case "강아지":{
          console.log(`${pet.name}는 하울링을 합니다.`);  
          break;
        }
        case "고양이":{
          console.log(`${pet.name}는 그루밍을 합니다.`);
          break;
        }
        case "새":{
          console.log(`${pet.name}는 날개가 있습니다.`);      
          break;
        }
      }
    }

    이렇게 구분이 가능한것은 속성에 스트링 리터럴을 사용했기 때문이다. 

    교집합이 생기기 위해서는 똑같은 스트링 리터럴을 가져야 하는데 그것은 불가능 하기 때문에

    집합의 관계들이 완전한 서로소 집합이 되어버린다.

     

    'TypeScript' 카테고리의 다른 글

    [TS기초]객체 타입  (0) 2023.06.15
    [TS기초]기본 타입  (0) 2023.06.13
    [Generic]제네릭 함수  (0) 2023.06.06
    Type Casting(타입 형변환)  (0) 2023.06.05
    인터프리터 언어, 컴파일 언어  (0) 2023.05.29
Designed by Tistory.