● 제네릭과 유니온 타입의 차이
제네릭을 배우면서, 제네릭을 도대체 왜 쓰는지에 대해 이해하기가 힘들었습니다. 유니온 타입보다 유동적이고 flexible하다.. 뭐 오케이 알겠는데. 타입스크립트의 엄격한 규칙성을 위해서는 유니온 타입을 쓰는게 더 맞지 않나 싶었습니다.
그냥 유니온 타입쓰면안돼? 라고 생각했는데 그 차이에 대해서 인지할 수 있었습니다..
만약에 어떠한 클래스가 있다고 가정해보겠습니다.
- 클래스는 인스턴스를 생성합니다.
- 이 인스턴스는 data라는 프로퍼티를 가지고 있습니다.
- 이 data 프로퍼티는 배열을 반환합니다.
위의 예시대로 코드를 짜보면, (+제네릭) 아래와 같게됩니다.
class DataStorage<T extends string> {
private data : T[] = [];
addItem(item :T){
this.data.push(item);
}
removeItem(item:T){
this.data.splice(this.data.indexOf(item), 1);
}
getItems(){
return [...this.data];
}
}
먼저 제네릭이 문자열만 받고 있기 때문에, data는 문자열로 이루어진 배열일 것입니다. 하지만 불리언값과 숫자도 받고싶다면?
아래와 같이 해결할 수 있겠습니다.
class DataStorage<T extends string | number | boolean> {
private data : T[] = [];
...
}
그런데 여기서 드는 의문점! 유니온 타입을 쓰면 같지 않나? 예를들어,
type UnionType = string | boolean | number;
class DataStorage{
private data: UnionType[] = [];
addItem(item: UnionType) {
this.data.push(item);
}
removeItem(item: UnionType) {
if (this.data.indexOf(item) === -1) {
return;
}
this.data.splice(this.data.indexOf(item), 1);
}
getItems() {
return [...this.data];
}
}
유니온 타입으로 모두 지정해버리면 안되나? 싶지만 명백한 차이가 있습니다.
제네릭은 하나의 타입으로 고정시킨다.
예를 들어, 클래스가 만드는 인스턴스의 data 프로퍼티가 문자열이면 문자열인 배열만, 숫자면 숫자열인 배열만, 불리언이면 불리언인 배열만 만들고 싶다면 제네릭을 사용하는 것이 좋습니다.
위의 유니온 타입은 배열에 문자열, 불리언, 숫자 값들이 혼합된 배열을 만들 수 있기 때문입니다.
예시에는 문자열, 불리언, 숫자만 넣었지만 만약에 객체나 또 배열을 넣었다면(이중배열)
따라서 indexOf라는 메서드를 활용할 수 없을 수도 있기때문에 제네릭을 활용하는게 맞습니당