Typescript

[Typescript] 제네릭 - 함수와 인터페이스에서의 사용법

joy_lee 2022. 7. 13. 17:20

제네릭이란?

TS코드에서 타입을 함수의 파라미터처럼 사용하는 방법이다.

함수의 재사용성을 위해 타입별로 여러 함수를 만들지 않고 하나의 함수로 여러 타입의 입력값을 처리할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 타입을 명시하지 않을 때(any타입)
function logText(text) {
    console.log(text);
    return text;
}
 
// 반환값은
logText(100); // 숫자 10
logText('hi'); // 문자열 hi
logText(true); // 진위값 true
 
 
// 제네릭을 사용할 때 <T>
function logText2<T>(text: T): T {
  console.log(text);
  return text;
}
 
// 함수를 호출할 때, 타입도 같이 입력해야 한다.
logText2<string>('hi');
cs

logText()에 숫자, 문자열, 진위값을 입력하기 위해 타입을 명시하지 않으면 any타입으로 간주한다.

logText2()에서는 제네릭을 사용해 입력값, 반환값의 타입을 입력받아 명시할 수 있다. 제네릭은 보통 T로 표시하며 다른 이름을 사용해도 상관없다.

 

 

제네릭을 사용하지 않는다면?

any타입으로 반환된 값은 API를 사용할 수 없다.

기존 타입 정의 방식으로 여러 타입의 입력값을 처리하려고 하면 함수를 중복 선언할 수 밖에 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 타입 명시를 위해 여러개 생성한 함수
function logString(text: string) {
    console.log(text);
    return text;
}
 
function logNumber(num: number) {
    console.log(num);
    return num;
}
 
// 유지보수 측면에서 좋지 않다.
const text = logString('hello');
const num = logNumber(10);

// text.trim(), num.isNaN() 등을 사용할 수 있지만...
cs

 

유니온 타입을 사용한다면?

유니온 타입을 사용한다면 여러 타입의 인자를 입력받을 수 있다.

하지만 입력에 대한 문제는 해결됐지만 반환값에 대한 문제는 해결되지 않는다.

1
2
3
4
5
6
7
8
// 유니온 타입 사용
function logText(text: string | number) {
    console.log(text);
    // 자동완성 불가능
    return text;
}
const a = logText('a'); // a 의 타입은 string | number
// a.split('') 사용불가 - 타입을 정확히 알 수 없음
cs

logText()를 통해 반환된 값이 string임이 분명하지만 TS에서는 구분하지 못하므로 ( string | number )로 인식해 관련된 메소드를 사용할 수 없다.

 

제네릭 사용

제네릭을 통해 함수 실행 시 전달받은 타입을 인자 타입과 반환 타입으로 사용하겠다고 명시할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
// 제네릭 사용
function logText<T>(text: T): T {
    console.log(text);
    return text;
}
 
const str = logText<string>('abc');
str.split(''); // TS에서 str이 string타입임을 알고있기 때문에 에러가 뜨지 않는다.
 
// 타입을 각각 선언하며 함수를 만들지 않아도 된다.
const login = logText<boolean>(true);
cs

타입에 구애받지 않고 자유롭게 입력할 수 있으며, 반환값의 타입도 명시되어 이후에 관련 메소드를 사용할 수 있다.

 

 

인터페이스에 제네릭 선언

인터페이스에서도 제네릭을 사용해 항목의 타입을 정의할 수 있다.

1
2
3
4
5
6
// 인터페이스에 제네릭 사용
interface Dropdown<T> {
    value: T;
    selected: boolean;
}
const obj: Dropdown<string> = { value: 'abc', selected: false }
cs

제네릭을 사용한 하나의 인터페이스로 여러가지 타입을 커버할 수 있다.

아래는 여러가지 dropdown 항목을 제네릭을 사용해 만든 코드이다.

1
2
3
4
5
6
7
8
9
10
11
const emails: DropdownItem<string>[] = [
  { value: 'naver.com', selected: true },
  { value: 'gmail.com', selected: false },
  { value: 'hanmail.net', selected: false },
];
 
const numberOfProducts: DropdownItem<number>[] = [
  { value: 1, selected: true },
  { value: 2, selected: false },
  { value: 3, selected: false },
];
cs

같은 DropdownItem 인터페이스를 가지고 다른 value의 타입을 가진 객체를 생성한다.

 

 

참고한 사이트

https://joshua1988.github.io/ts/guide/generics.html

 

제네릭 | 타입스크립트 핸드북

제네릭(Generics)의 사전적 정의 제네릭은 C#, Java 등의 언어에서 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징입니다. 특히, 한가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를

joshua1988.github.io

강의

https://www.inflearn.com/course/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%85%EB%AC%B8/dashboard

 

타입스크립트 입문 - 기초부터 실전까지 - 인프런 | 강의

타입스크립트를 시작하는 분들을 위한 강의입니다. 최신 자바스크립트 문법을 모르는 분들도 쉽게 배울 수 있도록 교과 과정을 구성하였습니다. 어렵게만 느껴지는 타입스크립트를 입문자 관

www.inflearn.com