Typescript_ 10. Generic_정의, 함수생성

Eunsu·2022년 3월 17일
0

@ TypeScript

목록 보기
13/14
post-thumbnail

◼ Generic

🚀 Generic이란?

제네릭은 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법이다. 한번의 선언으로 다양한 타입에 재사용이 가능하다는 장점이 있다.

또한 제네릭은 클래스와 인터페이스, 메서드를 정의할 때 타입을 파라미터로 사용할 수 있도록 한다. 타입 파라미터는 코드 작성 시 구체적인 타입으로 대체되어 다양한 코드를 생성하도록 도와준다.

🚀 Generic사용 이유

하나의 예제를 살펴보자

function printText(text:string):string{
	return text;
}

위 코드는 인자를 하나 넘겨받아 반환해주는 함수이다. 이 함수의 파라미터값과 리턴은 모두 string 타입으로 지정되어 있다. 여러가지 타입으로 사용하고 싶다면 any 타입을 사용해 수정할 수 있다.

function printText(text:any):any{
	return text;
}

하지만 여기서 문제점은 any는 모든 타입이기 때문에, 함수의 인자로 어떤 타입이 들어갔고, 어떤 값이 반환되는지 정확하게 알 수 없다는 점이다.

이러한 문제를 해결하는 것이 Generic 이다.

function printText<T>(text: T): T {
  return text;
}

여기서 함수뒤에 <T>라는 코드를 추가했다.
<T>는 Type의 약자로 제네릭을 선언할 때 T를 관용적으로 사용한다. 그리고 printText함수는 T라는 타입변수를 갖게 되며, 인자와 return의 type은 T라는 타입변수로 동일하다.

호출을 할 때에는

  const textResult1= printText<string>('Hello World!');
  const textResult2= printText('Hello World!');

이렇게 호출을 해 사용할 수 있다.

🚀 내장 제네릭 & 제네릭

하나의 예시를 들어보자

  const names:Array= ["Jenny","Julie"]

이런 코드를 작성하면 애러가 난다.

제네릭 타입은 1개의 타입의 변수를 넣어야 하는 제네릭 타입의 형태로 구성되어 있다. 배열 자체가 타입일 수 있으며, 그 자체로 타입을 구성하는 데이터의 목록이라고 할 수 있다. 객체가 어떤 데이터를 지니게 될지 모른다 하더라도, 그 자체로 타입이 된다.

배열 타입은 어떤 타입의 데이터가 저장되든 상관하지 않으며, 저장하는 요소가 문자열 목록, 숫자형 목록, 객체 목록, 혼합된 데이터의 목록이든 상관하지 않지만, 적어도 정보가 저장되는 것인지에 대해서는 확인해야 한다.

  const names:Array<string>= [];
  names[0].split(' ');

이것이 Generic Type이고, 타입스크립트에 내장된 타입이며 다른 타입과 연결된다. 타입스크립트는 names가 string으로 이루어진 배열임을 알고 있으며, string과 관련된 내장 메서드들을 호출해도 애러가 나지 않는다.

◼ Promise 예시

 const promise: Promise<string> = new Promise((resolve, reject) => {
 setTimeout(() => {
    resolve("success");
  }, 2000);
});
promise.then((data) => {
  console.log(data);
});

이렇게 타입스크립트에게 결과값에 대한 정보를 줄 수 있고, 어떠한 타입의 데이터를 반환하는지 알려준다.

🚀 제네릭 함수 생성

function mergeData(obj1: object, obj2: object) {
  return Object.assign(obj1, obj2);
}
const result = mergeData({ name: "Jenny" }, { age: 27 });
result.name;

이런 코드를 작성하면 애러가 남.

result에 name이라는 key가 있음에도 불구하고 애러를 낸다. 그 이유는 타입스크립트는 파라미터로 들어오는 타입이 object임만 알 뿐이지, 어떤데이터가 들어오는 지 모르기 떄문이다. 객체를 가져오고, 객체를 반환하는 것으로 추론하기 때문이다.

제네릭을 사용해 이 문제를 쉽게 해결할 수 있다. 데이터가 들어오는 타입을 제네릭을 이용해 변수로 넣어준다.

function mergeData<T,U>(obj1: T, obj2: U) {
  return Object.assign(obj1, obj2);
}
const result = mergeData({ name: "Jenny" }, { age: 27 });
result.name;

obj1의 타입은 T , obj2의 타입은 U 로 지정해줌으로써 어떤 데이터가 들어올 지 타입스크립트에게 알려주면, 타입스크립트 스스로 리턴값의 타입을 알아낼 수 있다.

타입스크립트에게 두 가지 다른타입을 입력했다고 알려준 것 뿐만 아니라, 이 함수를 정의할 때 이러한 타입들이 고정적으로 설정되지 않고, 함수를 호출 할 때 동적일 수 있도록 설정 할수 있도록 타입스크립트에게 알려주는 방법이라고 할 수 있다.

 type User = {
  name: string;
  hobbies: string[];
};
function mergeData<T, U>(a: T, b: U) {
  return Object.assign(a, b);
}
const user = mergeData<User, { age: number }>(
  { name: "Jenny", hobbies: ["sing a song", "play game"] },
  { age: 27 }
);
console.log(user);

이렇게 함수를 호출할 때 타입을 제네릭 타입으로 지정해주면 더 확실하게 된다.

profile
function = (Develope) => 'Hello World'

0개의 댓글