[TypeScript] 제네릭(Generic)

우지끈·2024년 12월 8일

제네릭(Generic)이란?

타입스크립트에서 제네릭(Generic)이란, 특정 타입에 의존하지 않는 유연한 코드를 작성할 수 있도록 도와주는 문법이다.
쉽게 말해, 제네릭은 타입을 위한 변수라고 생각하면 된다. 함수나 클래스, 인터페이스 등을 작성할 때 고정된 타입 대신 제네릭을 사용하면, 사용하는 쪽에서 타입을 지정할 수 있게 되어 코드의 재사용성유연성이 극대화된다.

function identity<T>(value: T): T {
  return value;
}

// 호출 시 타입을 지정
identity<string>("Hello"); // T는 string
identity<number>(123);     // T는 number

위의 예시 코드를 살펴보면 T는 제네릭 타입으로, 아무 이름이나 사용 가능하다.
즉, T 대신 Type, MyType, 아무거나 같은 이름도 다 사용할 수 있다. 그러나 일반적으로는 T(Type의 약자)를 사용하는 것이 관례이다.

제네릭 이름의 의미

  • 변수 이름처럼 아무거나 지정할 수 있다.
  • 그러나 의미를 알기 쉽게 지정하는 것이 좋다.
    - T (Type): 일반적인 타입
    • K (Key), V (Value): 키-값 구조를 다룰 때
    • E (Element): 배열 요소를 다룰 때

제네릭이 필요한 이유

타입스크립트에서 타입을 명시적으로 어노테이션해도 되는데, 굳이 제네릭을 쓰는 이유는 더 유연하면서도 안전한 코드를 작성하기 위함이다.

유연한 코드 작성

직접 타입을 어노테이션하면 고정된 타입에 대해서만 동작하지만,
제네릭은 다양한 타입에 대해 동작하는 코드를 하나의 구현으로 처리할 수 있다.

직접 어노테이션 하는 방식

function identityString(value: string): string {
  return value;
}

function identityNumber(value: number): number {
  return value;
}

// 매번 타입마다 새로운 함수를 작성해야 함
identityString("Hello");
identityNumber(123);

위의 경우 함수의 동작은 같지만, 타입마다 별도의 함수를 정의해야 해서 중복 코드가 늘어남을 알 수 있다.

제네릭 사용

function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

// 배열 타입에 따라 T가 자동으로 추론됨
getFirstElement<number>([1, 2, 3]); // T는 number
getFirstElement<string>(["a", "b", "c"]); // T는 string

제네릭을 사용하면 배열 타입에 따라 자동으로 T가 추론 된다. 따라서 하나의 함수로 다양한 타입을 처리할 수 있다.
getFirstElement 뒤에 명시적으로 <number><string>을 적어주지 않아도 자동으로 추론되지만 안정성을 위해 작성해주는게 좋다.


재사용성 극대화

제네릭을 사용하면 함수, 클래스, 인터페이스 등을 재사용 가능하게 설계할 수 있다.

직접 어노테이션 하는 방식

interface StringKeyValuePair {
  key: string;
  value: string;
}

interface NumberKeyValuePair {
  key: number;
  value: number;
}

위 경우에는 특정 타입만 처리하는 인터페이스를 여러 번 정의해야 하며, 타입이 추가될수록 중복 코드가 늘어날 것이다.

제네릭 사용

interface KeyValuePair<K, V> {
  key: K;
  value: V;
}

const stringPair: KeyValuePair<string, string> = { key: "id", value: "123" };
const numberPair: KeyValuePair<number, number> = { key: 1, value: 100 };

제네릭을 통해 하나의 인터페이스로 다양한 타입을 처리하는 것을 확인할 수 있다.


고정된 타입만 처리하는 함수나 클래스는 직접 어노테이션이 더 간단하고 적합할 수 있지만, 다양한 타입에 대해 동작해야 하는 코드에는 제네릭이 더 유리하다.

제네릭은 직접 어노테이션만으로는 해결할 수 없는 유연성안정성을 제공하며, 이를 통해 코드의 재사용성가독성 또한 크게 향상시킬 수 있으므로 잘 익혀두면 타입스크립트를 더 효율적으로 활용하는 데 큰 도움이 될 것 같다.

0개의 댓글