[TypeScript] - Generic
typescript 하면서 기본적인 문법은 프로젝트를 하면서 익혔는데, 이번에 공부하면서 generic 에 대해서 한번 집고 가고싶어서 정리해보려고 합니다.
공식문서를 살펴보면 generic은 재사용 가능한 컴포넌트를 생성하는 도구상자의 주요 도구라고 합니다.
이 도구는 단일 타입이 아닌 다양한 타입에서 작동하는 컴포넌트를 만들 수 있다고 써있습니다.
그러니까 다양한 타입에서 사용할 수 있는 코드를 만들때 유용한 도구인 것입니다.
1. Generic Type
간단하게 예시를 만들어 보겠습니다.
먼저 generic을 사용하지 않았을 경우를 만들어보겠습니다.
function identityNumber(arg: number): number {
return arg;
}
function identityString(arg: string): string {
return arg;
}
function identityAny(arg: any): any {
return arg;
}
이 identity 함수는 number, string, any에 따라서 분리가 되어 있지만 함수의 로직은 같으므로 이걸 컴포넌트화를 할 수 있을 것 같습니다.
// 보통 T를 많이 사용합니다.
// <> 를 통해 generic을 구현할 수 있습니다.
function identity<T>(arg: T): T {
return arg;
}
identity(1) // T : number
identity("123") // T : string
identity([1,2,3]) // T : number[]
이렇게 T를 통해서 사용자가 준 인수의 타입을 통해 해당 함수의 type을 결정하고 사용할 수 있게 합니다.
위의 코드보다는 아래의 코드가 확실히 범용성 있는 코드라는 것을 알 수 있습니다.
// 호출 방법
// 1. 제네릭 표현으로 안해도 컴파일 할때 인수 추론을 통해 타입을 정함
let id = identity("huni")
// 2.
let id = identity<string>("huni")
2. Generic Class
다음으로는 Class에서의 generic을 살펴보겠습니다.
클래스 이름 뒤에 < > 를 통해 generic 타입 매개변수 목록을 가질 수 있습니다.
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };
※ Class 에서 static이 있는 값은 제네릭을 사용할 수 없습니다.
class MyClass<T> {
static staticValue: T; // 에러 발생
}
3. Generic Extends
보통 Extends는 확장의 의미를 가지고 있습니다. 하지만 generic에서는 확장이 아닌 제약의 의미로 사용됩니다.
interface나 type과 같이 쓰입니다.
// 1.
// 이게 없다면 T에 length 메소드 사용이 불가 하기 때문에 오류 발생
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg;
}
loggingIdentity({length : 3);
// 2.
type Lengthwise = number | string;
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg;
}
loggingIdentity(3);
loggingIdentity("3");
4. generic을 사용하는 이유?
처음에 소개했던 것과 같이 재사용성 있는 컴포넌트를 만들때 유용하다고 말씀 드렸습니다. 하지만 다른 이유는 뭐가 있을 지 소개해보겠습니다.
이렇게 사용하면 좋은 이유는 무엇일까요?
- 코드의 재사용성이 증가한다.
- 타입 안전성이 올라간다 -> 컴파일 시 타입을 검사하기 때문에
(any 는 런타임 까지 알 수 없음) - 어려 종류의 타입을 다룰 수 있는 유연성
참고자료
https://www.typescriptlang.org/docs/ : typescirpt 공식문서
https://buly.kr/E78d4Nz : inpa tistory