제네릭(Generic)에 대해

oversleep·2025년 1월 23일
post-thumbnail

제네릭은:

타입을 매개변수처럼 사용할 수 있게 해주는 기능.
주로 TypeScript에서 많이 사용됨.

  1. 기본 문법:
// 제네릭 함수
function getFirstElement<T>(arr: T[]): T {
    return arr[0];
}

// 사용 예시
const numbers = [1, 2, 3];
const firstNumber = getFirstElement<number>(numbers); // 1

const strings = ['apple', 'banana', 'orange'];
const firstString = getFirstElement<string>(strings); // 'apple'
  1. 실용적인 예시:
// 제네릭 인터페이스
interface Box<T> {
    content: T;
}

// 숫자를 담는 박스
const numberBox: Box<number> = {
    content: 123
};

// 문자열을 담는 박스
const stringBox: Box<string> = {
    content: "Hello"
};

// 제네릭 클래스
class DataContainer<T> {
    private data: T;

    constructor(data: T) {
        this.data = data;
    }

    getData(): T {
        return this.data;
    }
}

const numberContainer = new DataContainer<number>(42);
const stringContainer = new DataContainer<string>("Hello");
  1. 여러 타입 매개변수 사용:
// 키와 값의 타입을 다르게 지정할 수 있는 Map
interface CustomMap<K, V> {
    get(key: K): V;
    set(key: K, value: V): void;
}

// 제네릭 함수에서 여러 타입 사용
function pair<T, U>(first: T, second: U): [T, U] {
    return [first, second];
}

const result = pair<string, number>("age", 25); // ["age", 25]
  1. 제네릭 제약조건:
// length 속성을 가진 타입만 허용
interface Lengthwise {
    length: number;
}

function logLength<T extends Lengthwise>(arg: T): number {
    console.log(arg.length);
    return arg.length;
}

logLength("hello");     // 가능 (문자열은 length 속성이 있음)
logLength([1, 2, 3]);   // 가능 (배열은 length 속성이 있음)
// logLength(123);      // 에러 (숫자는 length 속성이 없음)
  1. 실제 활용 예시:
// API 응답 처리를 위한 제네릭 함수
async function fetchData<T>(url: string): Promise<T> {
    const response = await fetch(url);
    return response.json();
}

// 사용자 타입 정의
interface User {
    id: number;
    name: string;
    email: string;
}

// 실제 사용
const user = await fetchData<User>('/api/user/1');
console.log(user.name); // 타입 안전성 보장
  1. 유용한 제네릭 유틸리티 타입들:
// Partial: 모든 속성을 선택적으로 만듦
interface Todo {
    title: string;
    description: string;
}

type PartialTodo = Partial<Todo>;
// { title?: string; description?: string; }

// Record: 키-값 쌍의 타입 정의
type PageInfo = Record<string, string>;
// { [key: string]: string }

// Pick: 특정 속성만 선택
type TodoPreview = Pick<Todo, 'title'>;
// { title: string }

제네릭의 장점:

  1. 타입 안전성: 컴파일 시점에 타입 체크
  2. 재사용성: 다양한 타입에 대해 동일한 로직 사용 가능
  3. 유지보수성: 타입 관련 버그를 줄일 수 있음
profile
궁금한 것, 했던 것, 시행착오 그리고 기억하고 싶은 것들을 기록합니다.

0개의 댓글