[TypeScript] 제네릭

종현·2023년 12월 31일

[TypeScript]

목록 보기
9/19

제네릭이란?

  • 타입스크립트를 사용하여 작성된 코드의 중복을 효과적으로 줄이고 고급 문법을 작성할 수 있게 도와준다.

  • 타입을 미리 정의하지 않고 사용하는 시점에 원하는 타입을 정의해서 사용할 수 있는 문법.

  • 함수의 파라미터와 같은 역할을 한다.

제네릭의 기본 문법

  • 함수를 호출할 때 제네릭에 문자열 데이터 타입인 string타입을 할당한다.

  • 할당된 타입이 T에 해당하는 부분에 적용된다.

function getItem<T>(item: T): T {
  return item;
}
// T는 string타입
getItem<string>('hi');
// T는 number타입
getItem<number>(99);

제네릭을 사용하는 이유는 뭘까?

중복되는 타입 코드의 문제점

  • 아래의 두 함수(첫번째, 두번째)는 단순히 파마미터로 받은 값을 return 해주는 함수이다.

  • 타입이 다른 것 빼고는 중복이 되고있는 코드이다.

  • 제네릭을 이용하여 가장 아래의 함수를 정의한다면 위의 두 함수를 따로 작성하지 않아도 된다.

function getText(text: string): string {
  return text;
}

function getNumber(num: number): number {
  return num;
}

function getItem<T>(item: T): T {
  return item;
}

getItem<string>('hi');
getItem<number>(99);

any를 쓰면 되는 거 아님?

  • any를 사용하게 되면 타입스트립트를 사용하는 장점을 상쇄시킨다.

  • any를 사용하게 되면 코드 자동 완성이나 에러의 사전 방지를 하지 못한다.

제네릭으로 해결되는 문제점

  • 타입 때문에 불필요하게 중복되던 코드를 줄일 수 있고, 타입이 정확하게 지정되면서 타입스크립트의 이점을 모두 가져갈 수 있다(코드 자동 완성, 에러의 사전 방지).

인터페이스에서 제네릭 사용하기

  • 중복된 value값을 가지고 있는 아래 코드의 세가지 인터페이스(ProductDropdown, StockDropdown, AddressDropdown)를 Dropdown 인터페이스로 사용하면 코드의 중복, 양도 줄어드는 동시에 타입스크립트의 장점을 가지고 갈 수 있다.
interface ProductDropdown {
  value: string;
  selected: boolean;
}

interface StockDropdown {
  value: number;
  selected: boolean;
}

interface AddressDropdown {
  value: { city: string; zipCode: string };
  selected: boolean;
}
// 위 3가지의 인터페이스를 대신해 사용할 수 있도록 제네릭으로 작성된 인터페이스
interface Dropdown<T> {
  value: T;
  selcted: boolean;
}

const product = Dropdown<string>;
const stock = Dropdown<number>;
const address = Dropdown<{ city: string; zipCode: string }>;

제네릭의 타입 제약

extends를 사용한 타입 제약

function logText<T extends string>(text: T): T {
  console.log(text);
}

logText<string>('hi'); // hi
logText<number> // T extends string으로 작성된 제네릭으로 number를 넘겨주면 에러가 발생한다.
  • 아래 코드의 함수는 T extends { length: number }의 타입을 가지고있다.

  • T는 length속성을 가지고 있는 string, array, object의 타입만 취급한다는 의미이다.

function lengthOnly<T extends { length: number }>(value: T) {
  reutrn value.length;
}


lengthOnly('hi');
lengthOnly([1, 2, 3]);
lengthOnly({text: 'abc', length: 123});

keyof를 사용한 타입 제약

function printKey<T extends keyof{ name: string; skill: string; }>(value: T) {
  console.log(value);
}

printKey('address'); // name과 skill이 string타입이라는 관점에서 데이터 타입이 같지만 keyof를 통해 타입을 name | skill(유니언 타입)으로 정의되어 있어 에러가 발생한다.

출처: 쉽게 시작하는 타입스크립트

profile
지속 가능한 성장 습관을 만들어 나가고 싶어요!

0개의 댓글