본문 바로가기

TypeScript

[generic] 다형성 타입 타입스크립트

제네릭(generic) 타입이란?

콜시그니쳐를 작성할 때 타입에 들어올 확실한 타입을 모를때 제네릭을 사용한다.

type SuperPrint = {
<T>(arr: T[]):void

}
const superPrint:SuperPrint = (arr) =>{
arr.forEach(i =>console.log(i))
}

superPrint([1,2,3,4])
superPrint([true,false,true,true])
superPrint(["asdf","b","c"])
superPrint([1,2,true,false])

<> 안에 넣으면 제네릭 타입이 된다 안에는 아무거나 써서 이름을 정할수있다 

 

제네릭은 타입스크립트가 타입을 받으면 자동으로 유추해서 정해준다.

 

이게 다형성 타입을 지정하는방법이다.

 

예시.

type SuperPrint = {
<T>(arr: T[]):T

}
const superPrint:SuperPrint = (arr) => arr[0]

const a = superPrint([1,2,3,4])
const b = superPrint([true,false,true,true])
const c = superPrint(["asdf","b","c"])
const d = superPrint([1,2,true,false,"홍대"])

리액트에서 사용할경우 위랑 다르게 사용한다.

 

제네릭을 여러개 사용하는경우

type SuperPrint = {
<T,M>(a:T[], b:M):T

}
const superPrint:SuperPrint = (a) => a[0]

const a = superPrint([1,2,3,4],"x")
const b = superPrint([true,false,true,true],1)
const c = superPrint(["asdf","b","c"], false)
const d = superPrint([1,2,true,false,"홍대"],[])

 

 

# 부가 설명



그렇다면 그냥 any를 넣는 것과 Generic의 차이는 무엇일까?

type SuperPrint = {
(arr: any[]): any
}

const superPrint: SuperPrint = (arr) => arr[0]

let a = superPrint([1, "b", true]);
// pass
a.toUpperCase();

any를 사용하면 위와 같은 경우에도 에러가 발생하지 않는다

type SuperPrint = {
(arr: T[]): T
}

const superPrint: SuperPrint = (arr) => arr[0]

let a = superPrint([1, "b", true]);
// error
a.toUpperCase();

Generic의 경우 에러가 발생해 보호받을 수 있다
* Call Signature를 concrete type으로 하나씩 추가하는 형태이기 때문!

type SuperPrint = {
(arr: T[], x: M): T
}

const superPrint: SuperPrint = (arr, x) => arr[0]

let a = superPrint([1, "b", true], "hi");

위와 같이 복수의 Generic을 선언해 사용할 수 있다