<aside> 🔥 Generic을 사용하면 클래스, 함수, interface를 다양한 타입으로 재사용할 수 있다.

선언할 떄는 타입 파라미터만 적어주고 생성하는 시점에 구체적인 사용하는 타입을 결정하는 것.

</aside>

<aside> 🔥 매개변수로 여러 타입을 받아야할 때,

앞서 알아본 방법으로

(1) 오버로드 사용

// 아래와 같이 여러 타입을 받아야 할 때

// (1) 오버로드 사용
function getSize(arr: string[]): number;
function getSize(arr: number[]): number;
function getSize(arr: number[] | string[]): number {
  return arr.length;
}

const arr1 = [1, 2, 3];
getSize(arr1);

const arr2 = ["a", "b", "c"];
getSize(arr2);

(2) 유니온 타입 사용

function getSize(arr: number[] | string[]): number {
  return arr.length;
}

const arr1 = [1, 2, 3];
getSize(arr1);

const arr2 = ["a", "b", "c"];
getSize(arr2);

하지만 타입이 계속 늘어나면 위 두가지 방법은 계속해서 추가해줘야한다.

이럴때 쓰는게 Generics

아래처럼 <T>로 지정해놓고 호출하는 곳에서 타입 지정!

// Generic
function getSize<T>(arr: T[]): number {
  return arr.length;
}

const arr1 = [1, 2, 3];
getSize<number>(arr1);

const arr2 = ["a", "b", "c"];
getSize<string>(arr2);

const arr3 = [false, true, true];
getSize<boolean>(arr3);

const arr4 = [{}, {}, { name: "Chul" }];
getSize<object>(arr4);

객체 형태일 떄

interface Mobile<T> {
  name: string;
  price: number;
  option: T;
}

const m1: Mobile<{ color: string; coupon: boolean }> = {
  name: "s21",
  price: 1000,
  option: {
    color: "red",
    coupon: false,
  },
};

const m2: Mobile<string> = {
  name: "s20",
  price: 900,
  option: "good ",
};

항상 name이 있고 string이 올때.

interface User {
  name: string;
  age: number;
}
interface Car {
  name: string;
  color: string;
}
interface Book {
  price: number;
}

const user: User = { name: "a", age: 10 };

const car: Car = { name: "bmw", color: "red" };
const book: Book = { price: 3000 };

function showName<T extends { name: string }>(data: T): string {
  return data.name;
}

showName(user);
showName(car);

</aside>