728x90

제너릭 이란?

제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다.

 

const names = ["jongyun", "minsoo"];

 

 

typescript의 타입 추론은 names의 타입이 string []이라고 말해준다.

string []이라는 타입은 사실 array 타입과 string 타입이 합쳐진 것이다.

 

const names2: Array<string> = [];

names2[0].split(""); // Not error

 

<> 꺽쇠를 사용하여 타입을 명시할 수 있는데 이게 바로 제너릭이다.

Array <string> 문자열 배열 타입이라고 명시하여 split 메서드를 사용하여도 에러가 발생하지 않는다.

 

javascript 에도 존재하는 promise를 예로 보자.

const promise: Promise<string> = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("This is done!");
  }, 2000);
});

promise.then((data) => {
  data.split(" "); // not Error
});

 

Promise 도 마찬가지로 제너릭으로 타입을 명시할 수 있다. 이렇게 타입을 주입하면 data.split과 같은 자동 단어 완성과

문자열이 아닌 number 가 resolve로 반환되었을 때 컴파일 타임에서 에러를 잡을 수 있다.

 

Generic function

 

두 객체를 병합하고 새 객체를 반환하는 함수가 있다고 가정해보자.

 

function merge(objA: object, objB: object) {
  return Object.assign(objA, objB);
}

 

console.log(merge({ name: 'Max' }, { age: 27 })); // Not error

const mergeObj = merge({ name: 'Max' }, { age: 27 });
mergeObj.name; // Error
mergeObj.age; // Error

merge를 실행하고 나서 name property와 age property에 접근하려고 하면 error를 발생시킨다.

 

 

타입 추론은 해당 함수의 return 값으로 object를 예상했다.

사실 자바스크립트에서 object 란 타입은 너무 광범위한 타입이다.

 

조금 더 타입 추론을 더 잘할 수 있고 유연하게 대처하기 위해서 Generic을 사용한다.

 

function merge2<T, U>(objA: T, objB: U) {
  return Object.assign(objA, objB);
}

 

보통 T를 제일 많이 쓰지만 꼭 무조건 써야 하는 것은 아니다.

T와 U라는 제너릭 타입을 명시하고 파라미터로 객체가 넘어올 때 타입을 지정한다.

 

const mergeObj2 = merge2({ name: 'Max' }, { age: 27 });
mergeObj2.name;
mergeObj2.age;

 

 

더 이상 에러도 발생하지 않고 리턴 타입은 T & U  = T 타입과 U 타입의 합집합이라고 말한다.

 

const mergeObj3 = merge2<{ name: string }, { age: number }>(
  { name: 'Max' },
  { age: 27 }
);

구체적으로 함수를 실행할 때 직접 타입을 적어줘도 문제는 발생하지 않는다.

하지만 이는 코드 중복이다. 타입 스크립트에서는 지양해야 되는 코딩 방식이다 최대한 타입 추론에게 맡기자

타입 추론이 잘못되었을 경우 그 경우에 따라 타입 캐스팅 제너릭 인터페이스 등등 을 활용하자

728x90

'TypeScript' 카테고리의 다른 글

Advanced Typescript 2  (0) 2021.11.29
Advanced Typescript - 타입스크립트 좀더 깊게 알아보기  (0) 2021.11.28
Typescript Interface  (0) 2021.11.28
Typescript Class  (0) 2021.11.27
typeorm database migration  (0) 2021.06.24