제네릭 (Generic) 함수란?
프로그래밍을 하다 보면 재사용성이 높은 코드가 필요할 때가 많은데,
어떤 타입이든 받을 수 있는 범용적인 함수를 만들고 싶을 때 (any 같은 치트키 말고)
그 때 제네릭 개념을 유용하게 사용한다.
1. 제네릭이란?
타입을 변수처럼 사용할 수 있도록 도와주는 기능.
즉, 함수를 선언할 때 특정 타입으로 고정하는 것이 아닌 어떤 타입이든 받을 수 있도록 유동적으로 설계할 수 있다.
예를 들어, func라는 제네릭 함수를 봐보자.
// 제네릭 함수
function func<T>(value: T): T {
return value;
}
여기서 `<T>`는 타입 변수로, 실제 함수가 호출될 때 전달된 값에 따라 타입이 결정된다.
2. 제네릭 함수 사용 예시
// 1.숫자 타입
let num = func(10); // T는 number로 추론됨
num.toFixed(); // ✅ 정상 동작
// 2.문자열 타입
let str = func("String"); // T는 string으로 추론됨
str.toUpperCase(); // ✅ 정상 동작
// 3.불리언 타입
let bool = func(true); // T는 boolean으로 추론됨
console.log(bool); // true
// 4.튜플과 같이 명시적으로 제네릭 타입 지정하기
let arr = func<[number, number, number]>([1, 2, 3]); // T는 [number, number, number] 타입
타입 변수 응용하기
1. 첫 번째 사례 : swap 함수
function swap<T, U>(a: T, b: U) {
return [b, a];
}
const [a, b] = swap("1", 2);
- swap<T, U> 함수는 두 개의 다른 타입의 인자를 받아 순서를 바꾼 배열을 반환하는 함수,
- T 와 U라는 두 개의 제네릭 타입을 사용하여 어떤 타입이든 받을 수 있도록 설계됨.
- "1" (문자열) 과 2(숫자) 를 입력하면 [2, "1"] 이 반환됨.
2. 두 번째 사례 : returnFirstValue 함수
function returnFirstValue<T>(data: [T, ...unknown[]]) {
return data[0];
}
let num = returnFirstValue([0, 1, 2]); // 0
let str = returnFirstValue([1, "hello", "mynameis"]); // 1
- 제네릭 타입 T를 사용하여 첫 번째 요소의 타입을 유지하면서 배열을 처리하는 함수.
- data: [T, ...unknown[]]은 첫 번째 요소가 T 타입이며, 이후에는 어떤 타입의 값이든 들어갈 수 있음을 의미.
- 입력 배열의 첫 번째 요소가 그대로 반환.
3. 세 번째 사례: getLength함수
interface InterfaceA {
length: number;
}
interface InterfaceB extends InterfaceA {}
//처럼
function getLength<T extends { length: number }>(data: T) {
return data.length;
}
let var1 = getLength([1,2,3]); // 3
let var2 = getLength("12345"); // 5
let var2 = getLength({length: 10}); // 10
let var4 = getLength(10); // 오류 발생.
- T extends { length: number } 를 사용해서 T가 반드시 length 속성을 가져야 함을 제한함.
- length 속성이 있는 객체는 사용할 수 있지만 var4처럼 length 속성이 없는 값은 사용할 수 없다.
여기서 궁금!..
인터페이스인데 `implements` 가 아닌 `extends` 를 사용하는 이유는 ???
- implements는 클래스에서만 사용되므로, 함수의 제네릭 타입 제한에는 사용할 수 없다고 한다.
- extends 는 타입을 확장하는 역할을 하기 때문에 사용이 가능함.
'프로그래밍 언어 > TypeScript' 카테고리의 다른 글
[TypeScript] Indexed Access & 여러 타입. (0) | 2025.03.08 |
---|---|
[TypeScript] 제네릭 인터페이스와 제네릭 타입 별칭 그리고 제네릭 클래스 (0) | 2025.03.06 |
[TypeScript] 클래스와 인터페이스 그리고 접근 제어자. (0) | 2025.03.05 |
[TypeScript] 타입 스크립트의 인터페이스,, (0) | 2025.02.26 |
[TypeScript] 함수 오버로딩과 타입 가드 (0) | 2025.02.26 |