일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 토이 프로젝트
- 타입스크립트
- 자바스크립트
- react pattern
- 코테
- react router dom
- Next.js
- React
- 리덕스
- 리액트 라우터 돔
- 스택
- styled component
- 코어자바스크립트
- reduxtoolkit
- 그리디
- 코딩테스트
- 동적계획법
- revalidatepath
- tanstack query
- 프로그래머스
- 리액트 패턴
- Supabase
- 토이프로젝트
- Form
- 프론트엔드
- TypeScript
- JavaScript
- React Query
- tailwind
- 리액트
- Today
- Total
느려도 한걸음씩
📘 TypeScript - 제네릭 본문
TypeScript를 사용하다 보면 여러 타입에 대해 재사용이 가능한 함수나 인터페이스를 만들고 싶을 때가 많습니다. 이럴 때 유용하게 사용할 수 있는 기능이 바로 제네릭(Generic)입니다.
이 글에서는 제네릭의 개념부터 활용 방법까지, 실제 예제를 통해 차근차근 알아보겠습니다.
🔹 제네릭이란?
제네릭(Generic)은 타입을 변수처럼 사용하는 문법입니다. 함수나 클래스, 인터페이스 등을 정의할 때 고정된 타입이 아닌, 나중에 사용할 때 결정될 수 있는 타입을 설정할 수 있게 도와줍니다.
간단한 예제로 시작해볼게요.
function getSize(arr: number[]): number {
return arr.length;
}
위 함수는 number[] 배열만 받을 수 있습니다.
const arr1 = [1, 2, 3];
getSize(arr1); // ✅ OK
const arr2 = ['a', 'b', 'c'];
getSize(arr2); // ❌ Error
arr2는 문자열 배열이기 때문에 오류가 발생하죠.
✅ 제네릭 함수로 해결하기
이제 제네릭을 이용해 getSize 함수를 모든 타입의 배열에서 사용할 수 있도록 만들어봅시다.
function getSize<T>(arr: T[]): number {
return arr.length;
}
여기서 는 타입 파라미터입니다. 함수가 호출될 때 T가 어떤 타입인지에 따라 자동으로 유추됩니다.
const arr1 = [1, 2, 3];
getSize<number>(arr1); // 3
const arr2 = ['a', 'b', 'c'];
getSize<string>(arr2); // 3
이렇게 하면 어떤 타입의 배열이든 사용할 수 있습니다!
🔸 인터페이스에서 제네릭 활용하기
제네릭은 함수뿐만 아니라 인터페이스나 클래스에서도 매우 유용합니다.
interface Mobile<T> {
name: string;
price: number;
option: T;
}
option의 타입을 제네릭으로 설정해두면, 나중에 다양한 타입으로 지정해줄 수 있습니다.
const m1: Mobile<{ color: string; coupon: boolean }> = {
name: 's21',
price: 1000,
option: {
color: 'red',
coupon: false,
},
};
const m2: Mobile<string> = {
name: 's20',
price: 900,
option: 'good',
};
이처럼 제네릭을 사용하면 다양한 상황에서 타입을 유연하게 설정할 수 있어요.
🔸 제네릭에 조건 달기 (extends)
제네릭을 쓸 때, 어떤 조건을 붙여야 할 경우도 있습니다.
예를 들어, 아래 함수는 객체를 받아서 그 객체의 name 프로퍼티만 반환합니다.
function showName<T extends { name: string }>(data: T): string {
return data.name;
}
T extends { name: string }는 T 타입이 반드시 name 속성을 가진 객체여야 한다는 조건입니다.
interface User {
name: string;
age: number;
}
interface Car {
name: string;
color: string;
}
interface Book {
price: number;
}
const user: User = { name: 'a', age: 10 };
const car: Car = { name: 'bmw', color: 'red' };
const book: Book = { price: 3000 };
showName(user); // ✅ OK
showName(car); // ✅ OK
showName(book); // ❌ Error: 'name' 프로퍼티 없음
이처럼 제네릭 타입에 조건을 걸어 타입 안정성을 확보할 수도 있습니다.
✅ 정리하며
제네릭은 다음과 같은 상황에서 매우 유용하게 사용할 수 있습니다.
- 함수나 클래스에서 타입을 재사용하고 싶을 때
- 하나의 인터페이스로 다양한 형태의 데이터를 다루고 싶을 때
- 타입에 조건을 걸어 더 안전한 코드를 작성하고 싶을 때
제네릭을 잘 활용하면 재사용성과 타입 안정성을 모두 챙긴 코드를 작성할 수 있습니다. 처음에는 조금 생소할 수 있지만, 예제를 따라가며 익히면 어렵지 않게 익숙해질 수 있습니다.
'FE develop > Typescript' 카테고리의 다른 글
📘 TypeScript - 유틸리티 타입 (0) | 2025.05.26 |
---|---|
📘 TypeScript - 클래스 (0) | 2025.05.23 |
📘 TypeScript - 리터럴, 유니온/교차 타입 (0) | 2025.05.23 |
📘 TypeScript - 함수 (1) | 2025.05.23 |
📘 TypeScript - 인터페이스 (0) | 2025.05.23 |