Union이란?

유니언은 ts에서 타입을 병합 할 수 있는 수많은 방법 중 하나이다.

Union으로 type 정의하기

type StringOrBooleanType = string | boolean; 

let stringOrBooleanType: StringOrBooleanType = '아이브';
stringOrBooleanType = true;

유니온을 사용하려면 | 을 사용하면 된다.
StringOrBooleanType은 string이 올 수 있고 boolean이 올 수 있게 된다.

stringOrBooleanType = undefined 
//에러 발생 undefined는 string, boolean타입이 아니기 떄문에

에러가 발생한다. type은 string과 boolean만 올 수 있는데 undefined가 왔기 때문이다.

type StrBoolNullType = string | boolean | null;

여러개도 가능하다. string, boolean, null을 저장할 수 있게 된다.

type StateTypes = 'DONE' | 'LOADING' | 'ERROR';

let state: StateTypes = 'DONE';
state  = 'LOADING';
// state = 'INITIAL' //에러발생 stateTypes에는 INITIAL이 없기 때문에

type을 굳이 string, number 등으로 안해도 된다. 사용자가 정의해서 사용할 수 있다.

리스트의 union

// string으로 구성된 리스트 또는 boolean으로 구성된 리스트
type StringListOrBooleanList = string[] | boolean[];

let strListOrBooleanList : StringListOrBooleanList = [
  '아이유',
  '김고은',
  '박소담'
]
strListOrBooleanList = [
  true,
  false,
  true
]

// strListOrBooleanList = [
//   true,
//   '아이유'
// ]//StringListOrBooleanList는 string리스트 또는 boolean리스트이기 때문에 혼합해서 사용할 수 없다.

StringListOrBooleanList를 string배열 또는 boolean배열을 받는다고 했다.
하지만 string, boolean을 같이 쓰게 되면 에러가 발생한다.

이것을 해결하는 방법은 다음과 같다.

type StrOrNumberList = (String | number)[];

let stringOrNumberList = [
  1,2,3,
  '아이유',
  '레드벨벳',
];
stringOrNumberList = [1,2,3]

stringOrNumberList = [
  '아이유',
  '레드벨벳'
]

// stringOrNumberList = [
//   true,
//   false
// ]

바뀐 점은
type StringListOrBooleanList = string[] | boolean[];
=>
type StrOrNumberList = (String | number)[];
이렇게 하면 string, number타입을 배열에 저장할 수 있다.
그러나 true, false등 boolean타입은 저장할 수 없다.

인터페이스의 union

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: '대한민국',

}

console.log(animalOrHuman);


지금 animalOrHuman변수의 타입을 AnimalOrHuman타입으로 한 것을 볼 수 있다. 하지만 실제로는 Human타입만 저장이 되어 있다.

animalOrHuman = {
  name:'오리',
  age:9
}
console.log(animalOrHuman); 
console.log(animalOrHuman.name);
console.log(animalOrHuman.age);
// console.log(animalOrHuman.address); //animalOrHuman은 이미 Animal타입으로 정의되었으므로 에러가 발생한다.
console.log((animalOrHuman as Human).address); //캐스팅하면 에러가 안난다. 이렇게 하면 안된다.


animalOrHuman변수의 타입을 AnimalOrHuman타입으로 정의했지만 실제로는 Animal타입이 사용되고 있다.
그래서 address를 출력하고자 하면 에러가 발생한다.
에러가 안나게 하고자 casting으로 Human타입으로 변경했지만 이렇게 하면 안좋다.

인터페이스의 union없이 그냥 쓰기

let animalOrHuman2 : {
  name: string;
  age: number;
}| {
  name:string;
  age:number;
  address:string;
} = {
  name:'최지호',
  age:32,
  address:'대한민국'
};

console.log(animalOrHuman2.address);
console.log(animalOrHuman2.name);
console.log(animalOrHuman2.age);

interface없이 선언을 동시에 할 수 있다. 이렇게 하면 interface 기능과 같지만 복잡하고 에러를 파악하기 힘들다.
웬만하면 type키워드를 사용해서 type을 형성한 다음 선언을 사용하는 것이 좋다.

서로 관계 없는 union 선언

type Person = {
  name: string;
  age: number;
}

type Cat = {
  breed:string;
  country:string;
}

type PersonOrCat = Person | Cat;
const personOrCat: PersonOrCat = {
  name:'코드팩토리',
  age:32,
  breed: 'Yorksire Terrier',
  country:'영국'
} // 유니언은 합집합의 개념이다. Person의 모든 것과 Cat의 모든 것을 사용할 수 있다 

PersonOrCat 타입을 선언했고 Person타입 또는 Cat타입이 올 수 있다.
그러면 Person, Cat타입에 있는 것을 전부 사용할 수 있다.

하지만

const personOrCat1: PersonOrCat = {
 // name:'코드팩토리',
  age:32,
  //breed: 'Yorksire Terrier',
  country:'영국'
} 

에러가 발생한다.
에러발생 이유는 Person도 될 수 없고 Cat도 될 수 없기 때문이다. 하나의 타입을 충족한 다음 그거에 초과되는 값이 타입이 와도 괜찮다. 반면에 어느타입도 충족되지 않은 상태에서 하면 에러가 발생한다.

profile
알고리즘 정리 블로그입니다.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN