-
대수 타입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