1. Generics ?
제네릭은 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법이다.
제네릭을 함수처럼 생각하면 쉽다.
function getText(text) {
return text;
}
getText('hi'); // 'hi'
getText(10); // 10
getText(true); // true
우리가 getText함수에 문자열을 넣으면 문자열이나오고 숫자를 넣으면 숫자가 나오고 불리언을 넣으면 불리언이 나오는 것 처럼
제네릭도 비슷한 개념이라고 생각하면 이해하기 쉽다.
자 위 자바스크립트 코드를 타입스크립트로 바꿔보자
function getText(text : string | number | boolean) {
return text;
}
getText('hi'); // 'hi'
getText(10); // 10
getText(true); // true
이렇게 작성할 것인가? 이보다 더 많은 타입이면 가독성은 더 떨어진다.
이럴때 사용할 수 있는게 바록 제네릭이다
아래 코드를 보자
function getText<T>(text: T): T {
return text;
}
getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
이렇게 생성 시점에 타입이 결정된다.
'T'는 일반적으로 많이 사용해서 사용한 것이다. 다른 문자를 적어도 잘 된다.
function getText<banana>(text: banana): banana {
return text;
}
getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
자 그럼 조금 알아 봅시다.
만약 배열을 받는다면 어떻게 해야할까요 ?
function getText<T>(text: T): T {
return text;
}
getText<number[]>([1,2,3]);
이런식으로 [] 대괄호를 해주면된다.
number [] 는 배열안에 number type이 있다는 소리이고 string [] 는 배열안에 string type이 있다는 소리이다.
(물론 제너릭이기에 getText([1,2,3]) 만 해도 타입스크립트가 알아서 추론해준다)
그렇다면 만약에 number와 string이 섞여 있다면 어떻게 할것인가 ?
function getText<T>(text: T): T {
return text;
}
getText<(number|string)[]>([1,2,3,"hi"]);
이렇게 괄호를 앞에 해주면 된다.
참고로 getText<(number|string)[]>을 안 해줘도 타입스크립트가 추론을 해준다.
그렇다면 이제는 함수자체가 배열만 받고 배열 안의 타입은 무엇이 될지 모른다면 어떻게할까?
function getArray<T>(text: T[]): T[] {
return text;
}
getArray([1,2,3,"hi"]);
매개변수에 T[] 대괄호를 넣어주면 된다.
제네릭 타입
제네릭 인터페이스에 대해 알아보자.
function logText<T>(text: T): T {
return text;
}
let str: <T>(text: T) => T = logText;
or
let str: {<T>(text: T): T} = logText;
or
type Str = <T>(text:T) => T
let str:Str = logText;
이런식으로 변수에 할당해줄 수도 있다.
(이역시도 let str = logText 만해도 타입스크립트가 알아서 추론해주기는 한다)
위와 같은 변형 방식으로 제네릭 인터페이스 코드를 다음과 같이 작성할 수 있다.
interface GenericLogTextFn {
<T>(text: T): T;
}
function logText<T>(text: T): T {
return text;
}
let myString: GenericLogTextFn = logText; // Okay
위 코드에서 만약 인터페이스에 인자 타입을 강조하고 싶다면 아래와 같이 변경할 수 있다.
interface GenericLogTextFn<T> {
(text: T): T;
}
function logText<T>(text: T): T {
return text;
}
let myString: GenericLogTextFn<string> = logText;
제네릭을 활용한 확장
아래와 같이 제네릭을 활용에서 확장할 수도 있다.
type Player<E> = {
name: string
extraInfo : E
}
type cocoExtra = {
age : number
}
type cocoPlayer = Player<cocoExtra>
const coco :cocoPlayer = {
name : "coco",
extraInfo : {
age : 27
}
}
'Typescript > 개념' 카테고리의 다른 글
[Typescript] tsconfig.json 옵션 (0) | 2023.08.22 |
---|---|
[TypeScript] Classes (0) | 2023.02.16 |
[Typescript] void (0) | 2023.02.14 |
[Typescript] 3. Polymorphism / generics (0) | 2023.01.19 |
[Typescript] declare (0) | 2022.12.28 |