[TS] 제네릭 타입

Yeong·2025년 3월 10일

🚀 "어떤 타입이 들어올지 모르지만, 나중에 사용할 때 정할 수 있도록 하는 기능"
🚀 "같은 코드로 여러 타입을 처리할 수 있도록 만들어주는 것"

📌 일반 함수

function doubleNumber(num: number): number {
  return num * 2;
}

console.log(doubleNumber(5)); // 10

✅ 여기서 num의 타입이 숫자(number)로 고정되어 있다.
즉, doubleNumber("hello") 같은 걸 하면 오류가 남 !!

📌 제네릭 함수

그런데 숫자뿐만 아니라 문자열도 두 배로 만들고 싶다면?
제네릭을 사용하면 타입을 미리 정해두지 않고 나중에 받을 수 있다.

  • 선언 방법<>내부에 임의의 기호심볼을 집어넣는다.
  • 보통 매개변수 기호로 T나 U를 많이 사용한다. ex) , <T, U>
function printValue<T>(input: T) {
    console.log(input);
}


//함수를 호출하는 예제
//<>내부에 원하는 type을 입력해준다.

printValue<string>("hello");
printValue<number>(7)

function double<T>(value: T): T {
  return value;
}

console.log(double<number>(5)); // 5
console.log(double<string>("hello")); // "hello"

✅ 여기서 T가 타입을 나타내는 변수이다!!!!!!
✅ double(5)를 하면 T가 number로 결정되고,
✅ double("hello")를 하면 T가 string으로 결정된다.

  • <T> 를 이용하여 매개변수의 타입과 리턴 타입이 동일하도록 만들어줄 수 있다.
function helloGeneric<T>(message: T): T {
	return message;
}
// 추론
helloGeneric('Mark');
helloGeneric(39);
helloGeneric(true);
// 지정
helloGeneric<string>('Mark');
helloGeneric<number>(39);
helloGeneric<boolean>(true);

✅ 제약 조건은 제너릭 T는 숫자 또는 문자여야 한다는 것이다.

즉, 제네릭을 쓰면 함수가 여러 타입을 처리할 수 있음 !!

📌 제네릭 제약조건

제네릭에 조건을 두어 사용하고 싶다면 extends 키워드로 제약조건을 걸 수 있다.

👉 예제 1

아무 객체가 되어도 상관없지만 일단은 객체여야한다는 조건

👉 예제 2

interface Lengthy {
  length: number;
}

function countAndDescribe<T extends Lengthy>(element: T): [T, string] {
  let descriptionText = 'Got no value';

  if (element.length === 1) {
    descriptionText = 'Got 1 element';
  } else if (element.length > 1) {
    descriptionText = `Got ${element.length} element`;
  }
  return [element, descriptionText];
}  
  
function merge<T extends object, U extends object>(objA: T, objB: U) {
  return Object.assign(objA, objB);
}  

🚀 왜 제네릭을 사용할까?
1. 같은 코드로 여러 타입을 사용할 수 있어서 재사용성이 좋다.
2. 코드를 더 안전하게 사용할 수 있다. (잘못된 타입이 들어오면 에러 발생)
3. 유지보수가 쉬워진다. (중복되는 함수를 여러 개 만들 필요 없음)

0개의 댓글