유니온은 조금 복잡한 타입을 구성할 수 있는 기능이라고 생각하면 된다. 다른 말로 타입을 병합할 수 있는 수많은 방법 중 하나다.
타입을 병합할 수 있는 방법은 많지만 유니온을 이용해 병합하는 경우가 제일 많고, 유니온이 필요한 로직이 굉장히 많다.
그러므로 유니온이 어떻게 동작하는지 정확하게 아는 것이 중요할 것이다!!
다음 예제를 보자.
type StringOrBooleanType = string | boolean;
let stringOrBooleanType: StringOrBooleanType = '태연';
stringOrBooleanType = true;
stringOrBooleanType 변수의 값의 타입은 string 혹은 boolean 둘 중 하나면 되므로 '태연'이 들어가도 문제가 없다.
그리고 이 변수를 boolean 타입인 true로 변경을 해도 문제가 없을 것이다.
그런데 여기서 만약에 undefined를 넣게 되면?
stringOrBoolenaType = undefined;
당연히 에러가 날 것이다. string 또는 boolean 타입이 아니기 때문이다.
그렇다면 지금까지는 2개의 타입을 가질 수 있는 타입을 만들었는데 그 이상도 만들 수 있을까?
3가지 타입을 가져야 하는 타입을 만들어 보자.
type StrBoolNullType = string | boolean | null;
이 또한 가능하고, 이 뒤에 무한히 추가할 수 있다!
type StateType = 'DONE' | 'ERROR' | 'LOADING';
state = 'LOADING'; // O
state = 'INITIAL'; // X
유니온으로 여러 개의 값들을 입력할 수 있고, 이 이외의 값은 입력할 수 없도록 만들 수가 있다는 것을 기억하자!
타입을 제한하거나 값을 제한하거나 원하는 값들의 영역만 입력할 수 있도록 만들 수 있는 굉장히 유용한 기능이다!!
리스트의 유니온에 대해서 살펴보자.
type StringListOrBooleanList = string[] | boolean[];
let stringListOrBooleanList: StringListOrBooleanList = [
'태연',
'권나라',
'윤아',
]; // O
let stringListOrBooleanList: StringListOrBooleanList = [
true,
false,
true,
]; // O
let stringListOrBooleanList: StringListOrBooleanList = [
'태연',
true,
'윤아',
]; // X
우리가 선언한 StringListOrBooleanList 타입에서 세 번째 예시는 올바르지 않다. 왜냐면 string으로만 구성된 리스트 혹은 boolean으로만 구성된 리스트여야 하기 때문이다.
세 번째 코드와 같이 리스트 하나에 여러 타입을 넣고 싶다면?
type StringOrNumber = (string | nmber)[];
let stringOrNumber: StringOrNumber = [
1, 2, 3, '태연'
];
stringOrNumber = [
11, 12, 13
];
stringOrNumber = [
'태연', '윤아', '권나라'
];
괄호 안에 넣고 싶은 타입을 넣어주면 된다. 또는 숫자만 넣어도 되고, 문자열만 넣어도 된다.
interface Animal {
name: string;
age: number;
}
interface Human {
name: string;
age: number;
address: string;
}
이 두 가지 타입을 가지고 유니온으로 구성해보자.
type AnimalOrHuman = Animal | Human;
let animalOrHuman: AnimalOrHuman = {
name: '권나라',
age: 32,
address: '대한민국',
};
여기서 Human 타입이라 가정하고, 프로퍼티를 입력했다. 그러면 타입스크립트도 내가 Human 타입을 입력한 것을 알고 있는지 확인해보자.
console.log(animalOrHuman);
타입을 확인하면 Animal | Human 타입이 아니라 Human 타입인 걸 확인할 수 있다.
이것을 타입스크립트가 어떻게 추론을 했을까? Human 타입이 되려면 address 프로퍼티가 있어야 한다. address 프로퍼티가 있으면 무조건 Human 타입이다. 그래서 address를 입력하면 자동으로 Human으로 추론한다.
다른 예제를 살펴보자.
animalOrHuman = {
name: '모서리',
age: 8,
};
console.log(animalOrHuman);
이것의 타입은 Animal 이다. 왜냐하면 address 프로퍼티가 없기 때문에 Animal 타입으로 추론한다.
console.log(animalOrHuman.name); // '모서리'
console.log(animalOrHuman.age); // 8
console.log(animalOrHuman.address); // X
위에서 이미 animalOrHuman은 Animal 타입으로 추론이 되었다. 그래서 address 프로퍼티는 존재할 수 없다는 것을 타입스크립트는 이미 알고 있다.

그러면 타입을 선언해서 유니온으로 형성하는 것이 좋은 이유를 알아보자.
let animalOrHuman2: {
name: string;
age: number;
} | {
name: string;
age: number;
address: string;
} = {
name: '권나라',
age: 32,
address: '대한민국',
};
console.log(animalOrHuman2.name); // 권나라
console.log(animalOrHuman2.age); // 32
console.log(animalOrHuman2.address); // 대한민국
이렇게 직접적으로 객체를 타입으로 선언하고, 각 프로퍼티를 출력하면 정상적으로 출력이 될 것이다.
animalOrHuman2 = {
name: '오리',
age: 6,
};
console.log(animalOrHuman2.name);
console.log(animalOrHuman2.age);
console.log(animalOrHuman2.address); // X
추가적으로 animalOrHuman2의 값을 위와 같이 변경하고, 출력을 하게 되면 address 프로퍼티에서 에러가 발생한다.

첫 번째 사진과는 표시된 내용이 다른 것을 볼 수 있다. 두 번째 사진에는 타입의 이름이 가독성이 떨어져서 읽기가 쉽지 않다. 그래서 웬만하면 type 키워드를 이용해 타입을 형성한 다음에 선언을 하는 것이 에러를 파악하는 데 유용하다.
위의 예제에서는 두 개의 타입이 공통된 프로퍼티를 가지고 있었다. 하지만 만약에 아예 프로퍼티가 다른 두 타입을 유니온으로 선언한다면?
type Person = {
name: string;
age: number;
};
type Cat = {
breed: string;
country: string;
};
type PersonOrCat = Person | Cat;
const personOrCat: PersonOrCat = {
name: '권나라',
age: 32,
}; // O, type: PersonOrCat
const personOrCat2: PersonOrCat = {
breed: 'Yorkshire Terrier',
country: 'England',
}; // O, type: PersonOrCat
const personOrCat: PersonOrCat = {
name: '권나라',
age: 32,
breed: 'Yorkshire Terrier',
country: 'England',
};
유니온의 재밌는 점은 Person과 Cat의 프로퍼티 모두 다 넣어도 괜찮다는 점이다. 유니온과 뒤에 배울 인터섹션은 집합의 개념으로 보면 좋다. 바로 합집합의 개념이다.
위의 코드에서 Cat의 일부분인 country나 breed만 빼도 된다. 마찬가지로 위의 코드에서 Person의 일부분인 name나 age 중 하나만 빼도 된다.
그런데 Person에서 하나, Cat에서 하나를 지우는 것은 안된다. 무언가 타입의 하나는 충족되어야 한다는 것이다!
다음 포스팅에서는 인터섹션에 대해서 알아보자.