TypeScript 제네릭
유연하고 재사용 가능한 코드 작성하기
TypeScript의 강력한 기능 중 하나인 제네릭(Generic)에 대해 알아보겠습니다. 제네릭을 사용하면 다양한 타입에 대해 동작하는 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
제네릭이란?
제네릭은 타입을 마치 함수의 매개변수처럼 사용할 수 있게 해주는 기능입니다. 이를 통해 여러 타입에 대해 동작하는 함수, 클래스, 인터페이스 등을 만들 수 있습니다. 제네릭을 사용하면 코드의 중복을 줄이고 타입 안정성을 유지할 수 있습니다.
제네릭 함수 예시
다음은 제네릭 함수의 간단한 예시입니다:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("Hello, TypeScript!");
let output2 = identity<number>(42);
console.log(output1); // "Hello, TypeScript!"
console.log(output2); // 42
이 identity
함수는 어떤 타입의 인자든 받아서 그대로 반환합니다.
<T>
는 타입 매개변수를 나타내며, 함수를 호출할 때 실제 타입으로 대체됩니다.
제네릭 인터페이스
제네릭은 인터페이스에도 사용할 수 있습니다:
interface Box<T> {
value: T;
}
let stringBox: Box<string> = { value: "A string value" };
let numberBox: Box<number> = { value: 42 };
이 예시에서 Box
인터페이스는 어떤 타입의 value
든 가질 수 있습니다.
TypeScript의 제네릭은 실무에서 다양한 상황에서 유용하게 사용됩니다. 다음은 실무에서 자주 사용되는 제네릭 코드 예시입니다:
API 응답 처리
API 응답을 타입 안전하게 처리하는 데 제네릭을 사용할 수 있습니다:
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
const response = await fetch(url);
return await response.json();
}
// 사용 예
interface User {
id: number;
name: string;
}
const result = await fetchData<User>('/api/user/1');
console.log(result.data.name); // 타입 안전성 보장
재사용 가능한 컴포넌트
React와 같은 프레임워크에서 재사용 가능한 컴포넌트를 만들 때 제네릭이 유용합니다:
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{renderItem(item)}</li>
))}
</ul>
);
}
// 사용 예
const users = [{ id: 1, name: '홍길동' }, { id: 2, name: '김철수' }];
<List items={users} renderItem={(user) => user.name} />
이 코드는 제네릭을 사용한 재사용 가능한 React 컴포넌트를 정의하고 있습니다. 각 부분을 자세히 설명해드리겠습니다:
- 인터페이스 정의:
interface ListProps<T> { items: T[]; renderItem: (item: T) => React.ReactNode; }
ListProps<T>
는 제네릭 인터페이스입니다.items: T[]
는 T 타입의 배열을 나타냅니다.renderItem: (item: T) => React.ReactNode
는 T 타입의 아이템을 받아 React 노드를 반환하는 함수입니다.
- 컴포넌트 정의:
function List<T>({ items, renderItem }: ListProps<T>) { return ( <ul> {items.map((item, index) => ( <li key={index}>{renderItem(item)}</li> ))} </ul> ); }
List<T>
는 제네릭 함수 컴포넌트입니다.items
와renderItem
을 props로 받습니다.items.map()
을 사용해 각 아이템을<li>
요소로 변환합니다.renderItem(item)
을 호출하여 각 아이템을 렌더링합니다.
- 사용 예:
const users = [{ id: 1, name: '홍길동' }, { id: 2, name: '김철수' }]; <List items={users} renderItem={(user) => user.name} />
users
배열을items
prop으로 전달합니다.renderItem
prop으로 각 사용자의name
을 반환하는 함수를 전달합니다.
이 컴포넌트는 어떤 타입의 배열이든 받아 리스트로 렌더링할 수 있으며, 각 아이템을 어떻게 표시할지 renderItem
함수를 통해 사용자가 정의할 수 있습니다.
제네릭의 장점
- 타입 안정성: 컴파일 시점에 타입 검사를 수행하여 런타임 오류를 줄입니다.
- 코드 재사용: 다양한 타입에 대해 동작하는 함수나 클래스를 만들 수 있습니다.
- 유연성: 필요에 따라 다양한 타입을 지정할 수 있습니다.
결론
제네릭은 TypeScript에서 매우 강력하고 유용한 기능입니다. 이를 통해 더 유연하고 재사용 가능한 코드를 작성할 수 있으며, 동시에 타입 안정성도 유지할 수 있습니다. 제네릭을 잘 활용하면 더 견고하고 확장 가능한 애플리케이션을 개발할 수 있습니다.
'JS' 카테고리의 다른 글
실무에서 자주 사용하는 lodash-es 함수 패턴2 (0) | 2025.01.19 |
---|---|
실무에서 자주 사용하는 lodash-es 함수 패턴1 (0) | 2025.01.19 |
유용한 lodash 숫자 관련 코드 예시 20가지 (0) | 2024.01.01 |
자주 쓰이는 lodash-es 객체 문법 15가지 (0) | 2024.01.01 |
자주쓰이는 lodash-es 배열 문법 17가지 (0) | 2024.01.01 |
댓글