[Typescript] Generic(제네릭)

2024. 8. 1. 09:52· TYPESCRIPT
목차
  1. 기본 문법
  2. 제네릭을 사용하는 이유
  3. 인터페이스에서 제네릭 사용하기
  4. 제네릭의 타입 제약
  5. extends를 사용한 제약
  6. keyof를 사용한 제약
  7. 제네릭 타입을 사용할 때 주의할 점

제네릭이란?

타입을 미리 정의하지 않고 사용하는 시점에 원하는 타입을 정의해서 사용할 수 있는 문법. 마치 함수의 파라미터와 같은 역할을 한다.

기본 문법

function getText<T>(text: T): T {
    return text;
}

getText<string>("hi");

 

T라고 선언된 모든 부분에서 string 타입이 들어간다.
다음과 같이 선언된 것과 같다.

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

마찬가치로 boolean, number, object 등 어느 타입이든 getText() 함수를 호출할 때 타입을 지정이 가능하다.

제네릭을 사용하는 이유

  • 중복된 타입 코드의 문제점
    • 같은 기능을 하는 함수에서 타입만 다를 경우 각각의 타입을 정의하여 여러 함수를 만들어줘야 하는 중복을 줄여준다
  • any를 쓰면 되지 않을까?
    • any를 사용하면 타입스크립트의 장점이 사라짐
    • 코드 자동완성이나 에러의 사전 방지 혜택을 받지 못함
function getText<T>(text: T): T {
  return text;
}

getText<number>(100);
getText<string>("hi");
getText<number>("hello"); // 타입 에러 발생

function getAny(text: any): any {
  return text.toString();
}

getAny("hi");
getAny(100);
getAny(true); // 실행과정에서 에러

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

// 이러한 인터페이스가 있다고 하게 되면 타입 코드가 많아지고 관리 포인트가 어려워 번거로운 작업이 된다.
interface ProdoctDropdown {
  value: string;
  selected: boolean;
}

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

interface AddressDropdown {
  value: { city: string; zipCode: string };
  selected: boolean;
}
// 인터페이스 이름 오른쪽에 <T>를 붙이고 내부 속성 중 제네릭으로 받은 타입을 사용할 곳을 T로 연결
interface Dropdown<T> {
  value: T;
  selected: boolean;
}


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

제네릭의 타입 제약

extends를 사용한 제약

모든 타입이 아니라 몇 개의 타입만 제네릭으로 받고 싶을 때

function embraceEverything<T extends string>(thing: T): T {
  return thing;
}

embraceEverything<string>("hi");
embraceEverything<number>(1000); // 에러 발생

// length 속성을 갖는 타입만 취급하고 싶을 때
// string, array, object
function getLength<T extends {length: number}>(value: T) {
  return value.length;
}

getLength("hi");
getLength(["a","b","c"];
getLength(100); // 타입 에러 발생

keyof를 사용한 제약

특정 키 값을 타입 지정

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

printKeys("hello") // 타입 에러
printKeys({ name: "mk", skill: "ts"});

제네릭 타입을 사용할 때 주의할 점

아래의 코드에선 타입 추론이 되지 않고 어떤 타입이 들어올지 모르기 때문에 함수 내부에서 에러 발생.
위에서 설명 extends를 활용한 힌트가 필요함

function printLength<T>(text: T) {
  console.log(text.length);
}

printLength<string>("hello");
function getLength<T extends {length: number}>(value: T) {
  return value.length;
}

getLength<string>("hello");

// 제네릭으로 받은 타입을 배열 형태로 정의하는 방법
function printLength<T>(text: T[]) {
  console.log(text.length);
}

printLength<number>([100]);
printLength<boolean>([true, false]);

'TYPESCRIPT' 카테고리의 다른 글

[Typescript] 타입 단언 (Type Assertion)  (0) 2024.09.23
[Typescript] Enum(이넘)  (0) 2024.07.16
[Typescript] 인터페이스(interface)[2]  (0) 2024.07.12
[Typescript] 인터페이스란? (interface)[1]  (0) 2024.07.09
[Typescript] 타입 종류  (0) 2024.06.11
  1. 기본 문법
  2. 제네릭을 사용하는 이유
  3. 인터페이스에서 제네릭 사용하기
  4. 제네릭의 타입 제약
  5. extends를 사용한 제약
  6. keyof를 사용한 제약
  7. 제네릭 타입을 사용할 때 주의할 점
'TYPESCRIPT' 카테고리의 다른 글
  • [Typescript] 타입 단언 (Type Assertion)
  • [Typescript] Enum(이넘)
  • [Typescript] 인터페이스(interface)[2]
  • [Typescript] 인터페이스란? (interface)[1]
seominki
seominki
seominki
minki's blog
seominki
전체
오늘
어제
  • LIST (44)
    • JAVASCRIPT (11)
    • TYPESCRIPT (7)
    • REACT & NEXT (6)
    • VUE (8)
    • WEBPACK (3)
    • FIREBASE (1)
    • LINUX (1)
    • GIT (2)
    • 자료구조 & 알고리즘 (2)
    • CS (0)
    • HTML&CSS (1)
    • AWS (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.v4.2.2
seominki
[Typescript] Generic(제네릭)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.