[Typescript] 제네릭 타입

Bam·2023년 9월 1일
0

Typescript

목록 보기
28/32
post-thumbnail

제네릭

제네릭(Generics)은 인터페이스, 클래스, 함수, 타입 별칭과 함게 사용할 수 있게 만들어진 기능입니다. 제네릭은 타입을 미리 지정하지 않고 다양한 타입에 대응할 때 사용하게 됩니다.

제네릭은 타입을 정의할때 기존에 사용하던 타입대신 T라는 문자로 지정해 제네릭 타입으로 정의합니다. 이때 문자 T타입 변수라고 합니다.

interface A<T> {}

type B<T> {}

function C<T>(arg: T): T {}

class D<T> {}

애로우 함수(ES6+)의 경우에는 제네릭 함수로 만드는 형태가 조금 다릅니다.

const func = <T extends {}>(arg: T): T => {};

extends 키워드를 통해 해당 변수가 제네릭 애로우 함수라고 알리는 것을 명시해야합니다.

이렇게 제네릭을 선언하면 T에는 호출 시점에 할당되는 타입이 결정됩니다. 함수같은 경우 매개변수로 숫자를 전달하면 호출때 Tnumber타입으로 취급되겠죠?

제네릭 호출

그러면 실제로 제네릭 함수를 만들어서 호출을 해보고 어떻게 동작하는지 확인해보겠습니다.

첫 입문 과정에서 제네릭 애로우 함수보단 function 명령 함수가 가독성이 좋다고 판단하여 function 명령 함수를 이용했습니다.

다음과 같이 매개변수 arg를 받아서 그대로 arg를 반환하는 제네릭 함수를 하나 생성했습니다.

function func<T>(arg: T): T {
  return arg;
}

console.log(func(123));
console.log(func('hello'));
console.log(func(true));
console.log(func([1, 2, 3]));

함수에 타입을 지정하지 않았음에도 불구하고 다양한 타입(위 코드에서는 number, string, boolean, number[])에 대응하여 정상적으로 동작했습니다.

위 코드에서는 매개변수로 전달할 값의 타입에 따라 자동적으로 타입 추론을 해서 T의 타입이 결정되었습니다.

하지만 다음과 같이 꺾쇠를 이용해서 T의 타입을 명시적으로 전달할 수도 있습니다.

function func<T>(arg: T): T {
  return arg;
}

console.log(func<number>(123));
console.log(func<string>('hello'));
console.log(func<boolean>(true));
console.log(func<number[]>([1, 2, 3]));

타입 변수의 활용

두 개의 타입 변수

타입 변수가 두 개가 필요하다면 다음 코드처럼 두 개의 타입 변수를 사용합니다.

function func<T, U>(arg1: T, arg2: U) {} //반환값은 타입 추론에 맡김

복합 타입 배열을 매개변수로 받는 함수

배열이 단일 타입이 아닌 여러 타입이 섞여있을 경우에는 타입 변수가 다음과 같이 추론됩니다.

function func<T>(arg: T): T {
  return arg;
}

func([123, 'hello']); // 타입 변수 T는 number | string 유니온 타입으로 추론

타입 변수 제약

타입 변수가 될 수 있는 타입에 제약을 두어 타입을 한정시킬 수도 있습니다. 이때는 extends 키워드를 사용합니다.

function func<T extends {}>(arg: T): T {
  return arg;
}

이때 extends 키워드 뒤의 중괄호{}에 제약 조건을 넣으면 타입 변수 T는 해당 조건에 맞는 타입만을 받게 됩니다.

대표적으로 length 프로퍼티가 있는 값을 받도록만 해보면 결과는 다음과 같습니다.

function func<T extends {length: number}>(arg: T): T {
  return arg;
}

console.log(func(123)); //Error!!!
console.log(func('hello')); //Success
console.log(func(true)); //Error!!!
console.log(func([1, 2, 3])); //Success

length 프로퍼티를 가질 수 있는 string, Array 객체타입은 무사히 받아들이지만, 가지지 못하는 number, boolean은 에러가 발생하게 됩니다.

0개의 댓글