TypeScript 배우기5

Parker.Park·2022년 8월 4일
0

TypeScript

목록 보기
5/8

타입스크립트 시작하기, Inflearn


Generic

제네릭은 타입을 동적으로 정의할 수 있는 기능이라고 한다. 그렇기때문에 재사용성을 높일 수 있는 타입이라 할 수 있다.

function f1(a: number, size: number): number[] {
  const arr: number[] = [];
  for (let i = 0; i < size; i++) {
    arr.push(a);
  }
  return arr;
}

function f2(a: string, size: number): string[] {
  const arr: string[] = [];
  for (let i = 0; i < size; i++) {
    arr.push(a);
  }
  return arr;
}

위 예시와 같이 f1, f2를 만들어 number타입과 string타입을 구분지을 수 있었다. 아니면 function-overload를 통해서 통합하여 만들수도 있다.

function f1(a: number, size: number): number[];
function f1(a: string, size: number): string[];
function f1(a: number | string, size: number): Array<number | string> {
  const arr: Array<number | string> = [];
  for (let i = 0; i < size; i++) {
    arr.push(a);
  }
  return arr;
}

이전 함수에 비하여 효율적이지만 타입을 추가할경우 f1을 수정해줘야하는 번거로움이 발생할 것이다. 이것을 줄여주는 방법으로 제네렉타입을 사용하는 것이라고 한다.

generic 사용

제네릭은 다음과 같이 사용한다고 한다.

function f1<T>(a: T, size: number): T[] {
  const arr: T[] = [];
  for (let i = 0; i < size; i++) {
    arr.push(a);
  }
  return arr;
}

const a1 = f1<number>(1,5)
const a2 = f1<string>("a",10)

const a3 = f1("z", 10);
const a4 = f1(5, 10);

함수에서 제네렉은 함수 혹은 클래스 옆에<T>와 같이 사용하며, "T"는 관용적인 식별자 일 뿐이다. T가 공통적으로 매개변수 "a"와 return 타입과 함수안에서 arr 타입을 정해주고 있다. 변수 a1, a2처럼 타입을 지정해주어도 되지만, a3, a4 처럼 타입스크립트에서 자동으로 지정해 줄 수 있다.

generic - extends 키워드

제네릭에서 extends 키워드를 사용하여 타입을 제한하거나 확장 할 수 있다고한다.

function f1<T extends number | string>(a: T): T {
  return a;
}

console.log(f1(1));
console.log(f1("a"));

console.log(f1(true));
//error TS2345: 
//Argument of type 'boolean' is not assignable to parameter of 
//type 'string | number'.

위 예시와 같이 T라는 제네렉 타입에 number타입과 string타입으로 제한해 놓으면 그 밖에 타입인 불리언타입이 들어왔을 경우 에러가 뜨는것을 알 수 있었다.

interface Animal {
  name: string;
  age: number;
}

interface Cat extends Animal {
  cutable: boolean;
}

function swapProperty<T extends Cat, K extends keyof Animal>(
  p1: T,
  p2: T,
  key: K
): void {
  const temp = p1[key];
  p1[key] = p2[key];
  p2[key] = temp;
}

const p1: Cat = {
  name: "nyang",
  age: 2,
  cutable: true,
};

const p2: Cat = {
  name: "nyangnyang",
  age: 3,
  cutable: true,
};

console.log(p1, p2);
//{ name: 'nyang', age: 2, cutable: true } 
//{ name: 'nyangnyang', age: 3, cutable: true }
swapProperty(p1, p1, "name");
console.log(p1, p2);
//{ name: 'nyang', age: 2, cutable: true }
//{ name: 'nyangnyang', age: 3, cutable: true }

위 예시에서는 인터페이스 Animal 을 상속받은 인터페이스 Cat을 선언하였고, 제네릭을 활용하여 swapProperty라는 함수를 정의하였다. "T" 는 인터페이서 Cat을 제한한 것이고, K는 extents keyof라는 인터페이스 Animal에서 key값만 가져올 수 있게 제한하였다. 즉, "name"과 "age"를 의미하는 것이다.

참조

[제네릭, TypeScript Guidebook, 2022년08월8일 접속]
https://yamoo9.gitbook.io/typescript/generics

profile
개발자준비중

0개의 댓글