[Effective Typescript] Union Type과 Intersection Type

강은비·2022년 6월 20일
0

TS

목록 보기
5/10
post-thumbnail

Union Type

  • 유니온 타입은 변수가 여러 타입을 가질 수 있는 경우에 주로 사용된다.
  • | 연산자를 이용해 여러 타입을 하나로 묶어 그 중 하나의 타입을 가진다는 의미로 사용된다.

Example


function getAge(age: number | string) {
  if (typeof age === 'number') {
    age.toFixed();
    return age;
  }
  if (typeof age === 'string') {
    return age;
  }
  return new TypeError('age must be number or string');
}

Intersection Type

  • 여러 타입을 모두 만족하는 하나의 타입을 의미한다.
  • & 연산자를 이용해 여러 타입을 하나로 묶는다.

Example

interface Person {
	name: string;
}

interface LifeSpan {
	birth: Date;
    deaht?: Date;
}

type PersonSpan = Person & LifeSpan;

const ps : PersonSpan = {
	name: 'Alan Turing',
  	birth: new Date('1912/06/23'),
} // 정상!!

+) extends 키워드 사용하기

// extends 키워드를 사용하여 PersonSpan을 정의할 수 있다.

interface Person {
	name: string;
}

interface PersonSpan extends Person {
	birth: Date;
    deaht?: Date;
}

⚠️ Union Type을 사용할 때 주의해야 할 점

interface Person {
  name: string;
  age: number;
}

interface Developer {
  name: string;
  skill: string;
}

function introduce(someone: Person | Developer) {
  someone.name; // O 정상 동작
  someone.age; // X 타입 오류
  someone.skill; // X 타입 오류
}
  • 위 코드에서 someone 파라미터의 타입이 유니온 타입을 통해 정의되었고, Person이거나 Developer이다.
  • 타입스크립트 관점에서 보면 introduce 함수가 호출될 때 someone 파라미터에 Person 타입이 올지 Developer 타입이 올지 모른다.
  • 그래서 name은 두 타입의 공통속성이기에 정상 동작하지만, ageskill은 공통 속성이 아니기 때문에 타입 오류가 발생된다.

아래와 같이 코드를 수정해야 한다.

  1. '속성 in 객체' 방식 이용
    function introduce(someone: Person | Developer) {
      if ("name" in someone){
      	someone.name;  // O 정상 동작
      }
    }
  1. tagged union (태그 기법)
    interface Person {
      name: string;
      age: number;
      kind: "person";
    }
    
    interface Developer {
      name: string;
      skill: string;
      kind: "developer";
    }
    
    function introduce(someone: Person | Developer) {
      if (someone.kind == "developer"){
      	someone.skill // O 정상동작
      }
    }
  1. class
    interface는 타입으로만 사용할 수 있지만, class는 타입과 값으로 모두 사용할 수 있다.
    class Person {
    	constructor(public name: string, public age: number){}
    }
    
    class Developer {
      	constructor(public name: string, public skill: string) {}
    }
    
    function introduce(someone: Person | Developer) {
      if (someone instanceof Developer){
      	someone.skill // O 정상동작
      }
    }

0개의 댓글