Generic 함수에서 사용하기
- 제네릭은 타입 안정성을 유지하면서 재사용 가능하고 일관된 코드를 작성하도록 도와주는 기능이다.
제네릭 기본 사용법
- 함수명 옆에 <타입변수명> 을 명시하여 어떤 타입을 사용할지 명시한다.
- 해당 <타입변수명>을 매개변수 타입이나 반환 타입에서 이용할 수 있다.
- 호출할 때는 함수명 옆에 타입변수명이 아닌 사용할 타입명을 명시하면 된다.
function foo<T>(value: T): T {
return value;
}
// 호출할 때는 함수명 옆에 타입변수명이 아닌 사용할 타입명을 명시하면 된다.
foo<string>("abc");
여러개의 제네릭 타입 사용하기
,
를 이용하여 몇개든 이어주면 된다.
function bar<Type1, Type2, Type3>(a: Type1, b: Type2, c: Type3) {
return {
a,
b,
c,
};
}
bar<number, string, boolean>(10, "10", true);
제네릭이 해결하는 문제: 타입에 특화된 함수를 일반화
- 애플리케이션에서 작성한 함수의 타입을 일반화하여 같은 로직을 여러 타입에 적용
제네릭 적용 전
- number 에도 이 로직을 적용하고 string 에도 적용하고 싶어서 두가지 타입의 중복된 함수를 선언한다.
function firstNumber(arr: number[]): number {
return arr[0];
}
function firstString(arr: string[]): string {
return arr[0];
}
// 각 타입에 대해 다른 함수를 사용한다.
let numbers1 = [1, 2, 3];
let firstNum1 = firstNumber(numbers1); // 숫자라 firstNumber 를 사용
let strings1 = ["hello", "world"];
let firstStr1 = firstString(strings1); // 문자라 firstString 을 사용
제네릭 적용 후
- 모든 타입에서 작동할 수 있는 단일 함수를 작성할 수 있다.
- 숫자나 문자열과 같은 구체적인 타입을 지정하는 대신 T로 표시 되는 타입 변수를 사용한다.
function first<T>(arr: T[]): T {
return arr[0];
}
// 각 타입에 대해 같은 함수를 사용한다.
let numbers2 = [1, 2, 3];
let firstNum2 = first(numbers2); // T is number
let strings2 = ["hello", "world"];
let firstStr2 = first(strings2); // T is string
제네릭을 사용하는 이유
- 재사용성: 함수나 클래스를 한번 작성하고 다른 유형에 계속 재활용이 가능하다.
- 타입 안정성 유지: 타입스크립트가 여전히 타입을 검사하고 잘못된 타입에 오류를 표기해준다.
- 유연성: 타입 안정성을 희생하지 않고도 코드를 더 유연하게 작성 가능하다.
class Car {
brand: string;
carName: string;
constructor(brand: string, codeName: string) {
this.brand = brand;
this.carName = codeName;
}
}
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
클래스 생성자를 제네릭으로 적용하기
- 생성자의 타입 시그니처 표현 방법이
new (매개변수): 반환 타입
이었던 것을 기억하자. - 모든 클래스 인스턴스가 사실 타입스크립트와 자바스크립트 관점에선 객체(
{}
)였음을 상기해보면 편하다. extends
이후new (...args: any[]): {}
는 결국 모든 클래스의 생성자 시그니처를 품는다고 생각하면 된다.
function instantiator<T extends { new (...args: any[]): {} }>(
constructor: T,
...args: any[]
) {
return new constructor(...args);
}
console.log(instantiator(Car, "현대", "소나타"));
console.log(instantiator(Person, "Jake Seo", 10));
반응형
'Typescript' 카테고리의 다른 글
TS032. 타입스크립트의 Visibility 키워드들 (0) | 2024.01.01 |
---|---|
TS031. 타입스크립트의 Abstract Class (0) | 2024.01.01 |
TS030. 타입스크립트 클래스에서 메서드, 속성 오버라이딩 (0) | 2024.01.01 |
TS029. 타입스크립트 클래스 상속 (0) | 2023.12.31 |
TS028. 타입스크립트 인터페이스를 클래스에 사용하기 (0) | 2023.12.31 |