제네릭을 사용하는 이유
`any` 타입을 사용하면 모든 값을 허용할 수 있지만, 타입 안정성이 떨어집니다. 반면 제네릭은 호출 시점에 타입을 지정해, 코드의 의도를 명확히 하고 오류를 줄입니다. 제네릭은 한 함수나 인터페이스가 다양한 타입을 처리할 수 있도록 합니다. 예를 들어, 단순한 배열 처리 함수를 생각해 봅시다. 만약 숫자 배열과 문자열 배열에 대해 각각의 함수를 만들 필요 없이, 제네릭을 사용하면 하나의 함수로 모든 타입을 처리할 수 있습니다.
제네릭 함수 예제
function reverseList<T>(list: T[]): T[] {
return list.reverse();
}
const numbers = reverseList<number>([1, 2, 3]);
const words = reverseList<string>(["가", "나", "다"]);
console.log(numbers); // 출력: [3, 2, 1]
console.log(words); // 출력: ["다", "나", "가"]
`T`는 타입 파라미터로, 호출 시 지정된 타입에 따라 동작합니다.
제네릭 인터페이스
제네릭 인터페이스는 객체의 구조를 정의할 때, 타입 파라미터를 활용하여 유연하고 재사용 가능한 타입을 설계할 수 있게 해줍니다.
interface MessageStore<T> {
content: T;
timestamp: Date;
getMessage(): T;
}
class SimpleStore<T> implements MessageStore<T> {
constructor(public content: T, public timestamp = new Date()) {}
getMessage(): T {
return this.content;
}
}
const textStore = new SimpleStore<string>("안녕하세요");
const countStore = new SimpleStore<number>(42);
console.log(textStore.getMessage()); // 출력: 안녕하세요
console.log(countStore.getMessage()); // 출력: 42
`MessageStore<T>`는 메시지와 타임스탬프를 관리하며, `T`로 다양한 타입을 처리합니다.
제네릭 인터페이스에 제약 적용하기
때로는 제네릭 타입이 특정 프로퍼티를 반드시 포함해야 하는 경우가 있습니다. 이럴 때는 extends 키워드를 사용해 제네릭 타입에 제약을 걸 수 있습니다.
interface Named {
name: string;
}
interface Repository<T extends Named> {
entries: T[];
findByName(name: string): T | undefined;
}
class DataRepo<T extends Named> implements Repository<T> {
constructor(public entries: T[]) {}
findByName(name: string): T | undefined {
return this.entries.find(entry => entry.name === name);
}
}
const repo = new DataRepo<{ name: string; age: number }>([
{ name: "민수", age: 25 },
{ name: "지영", age: 30 },
]);
console.log(repo.findByName("지영")); // 출력: { name: "지영", age: 30 }
`T`는 `Named`를 확장해야 하므로 `name` 속성을 필수로 가집니다.
'TypeScript' 카테고리의 다른 글
[TypeScript] 타입 좁히기(Narrowing): 타입을 안전하게 다루기 (1) | 2025.02.26 |
---|---|
[TypeScript] 프로퍼티 데코레이터 사용하기 (0) | 2025.02.26 |
[TypeScript] 인터페이스와 클래스 언제 사용할까? (1) | 2025.02.25 |
[TypeScript] 상속: 코드 재사용의 핵심 (0) | 2025.02.25 |
[TypeScript] Getters와 Setters 사용하기 (0) | 2025.02.25 |