본문 바로가기
Javascript/Typescript

[Typescript] Generic - 1

by 같이긍뱅와 2023. 11. 18.
function toObj(a: string, b: string): { a: string; b: string };
function toObj(a: number, b: number): { a: number; b: number };
function toObj(a: boolean, b: boolean): { a: boolean; b: boolean };
function toObj(
  a: string | number | boolean,
  b: string | number | boolean
): { a: string | number | boolean; b: string | number | boolean } {
  return { a, b };
}

toObj("A", "B");
toObj(1, 2);
toObj(true, false);

 

 

이렇게 여러 타입에 대응 되는 함수를 만들기 위해서 함수 오버로딩을 많이 하지않을 수는 없을까?

답은 제네릭

 

// 꼭 T로 안지어도 되지만 많이 이렇게 씀
function toObj<T>(a: T, b: T): { a: T; b: T } {
  return { a, b };
}
toObj<string>("A", "B");
toObj<number>(1, 2);
toObj<boolean>(true, false);
toObj(null, null)

 

T로 string, number boolean을 넣어줬다.

4번째 toObj가 사용가능한 이유는 T가 타입 추론을 통해 null이 들어갔기 때문에 뒤에 나오는 T도 자연스럽게 null이 들어갔다.

 

function toObj<T extends string | number | boolean>(a: T, b: T): { a: T; b: T } {
  return { a, b };
}
toObj<string>("A", "B");
toObj<number>(1, 2);
toObj<boolean>(true, false);
toObj(null, null) // Error

 

extends를 통해 제네릭 T의 type을 제약할 수 있다. 이 경우 4번째 경우는 사용할 수 없다. 

 

interface ToObj<T> {
  a: T;
  b: T;
}

function toObj<T extends string | number | boolean>(a: T, b: T): ToObj<T> {
  return { a, b };
}

toObj<string>("A", "B");
toObj<number>(1, 2);
toObj<boolean>(true, false);

 

함수뿐 아니라 interface, Type에서도 사용가능

 

interface User<T, U, V> {
  name: T,
  age: U,
  isValid: V,
}

const heropy: User<string, number, boolean> = {name: 'Heropy', age: 85, isValid: true}

type Animal<T,U,V> = {name: T, age: U, isValid: V} | [T, U, V];

const dragon: Animal<string, number, boolean> = ['Evan', 77, false];

 

여러개 사용도 가능 하다 순서대로 타입을 선언할 수 있음

 

Class에 제네릭을 적용해서 사용하는 예시

class Basket<T> {
  public items: T[];
  constructor(...rest: T[]) {
    this.items = rest;
  }

  putItem(item: T) {
    this.items.unshift(item);
  }
  takeOutItems(count: number) {
    return this.items.splice(0, count);
  }
}

const fruitsBasket = new Basket('Apple', 'Banna', 'Cherry') // T가 string으로 타입 추론 이후 T는 string 된다
fruitsBasket.putItem('Orange')
const fruits = fruitsBasket.takeOutItems(2)
console.log(fruits) // ['Orange', 'Apple']
console.log(fruitsBasket.items) // ['Banana', 'Cherry']

const moneyBasket = new Basket(100, 1000, 10000)  // T가 number로 타입 추론
moneyBasket.putItem(50000)
const money = moneyBasket.takeOutItems(2)

'Javascript > Typescript' 카테고리의 다른 글

Vercel Dev api 등록시 에러 해결  (0) 2023.12.01
VITE 환경에서 .env 사용법  (1) 2023.12.01
[Typescript] abstract class  (0) 2023.11.13
[Typescript] 함수 오버로딩  (0) 2023.11.12
[Typescript] this 타입  (0) 2023.11.12

댓글