본문 바로가기
script/Typescript

Typescript polymorphism, generic

by devved 2023. 1. 8.
반응형

polymorphism(다형성)

generic type
concrete type 을 사용하는 대신 쓸 수 있는 방법으로 type의 placeholder같은 것(typescript가 타입을 유추한다)

// 제네릭 안쓰고 아래와같이 표기해줄 수도 있지만, 여러 type이 섞여있는 경우 결국 경우의 수가 너무 많이 생김! 
// (arr: (number | boolean) []) : void

// generic 선언방법
// <generic 제네릭변수명> 으로 지정하여 type generic으로 설정
// 예시 1
type <TypePlaceholder>(arr: TypePlaceholder []) : TypePlaceholder
// 예시 2
type SuperPrint = <T>(a: T[]) => T

// 보통 예시 2처럼 T, M, V 이런식으로 정해주는 경우가 많음

사용방법

const superPrint: SuperPrint = ( a ) => a[0]
/* 동일한 의미의 코드
function superPrint<T>(a: T[]) {
    return a[0]
}
*/

superPrint([1, 2, 3, 4])
superPrint([true, false, true])
superPrint(['a', 'b', 'c'])
superPrint([1, 2, false, 'c'])

// generic 예시2 
type A = Array<number> // Array 자체가 제네릭을 받고있음 그 후 <number>로 타입제한해주는 것

let a: A = [1, 2, 3, 4]
let b: A = ['1', '2', '3'] // error

 

generic 심화

// 여러개의 generic type 지정하기
type SuperPrint = <T, M>(a: T[], b: M) => T

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

superPrint([1, 2, 3, 4], "x")
superPrint([true, false, true], true)
superPrint(['a', 'b', 'c'], 10)
superPrint([1, 2, false, 'c'], [])

// 재사용 빌드업
type Player<E> = {
    name: string
    extraInfo : E 
}

const nico: Player<{favFood: string}> = {
    name: "nico", 
    extraInfo: {
        favFood: "KIMCHi"
    }
}
/*
위와 동일한 의미의 코드
type NicoPlayer = Player<{favFood:string}>

const nico: NicoPlayer = {
    name: "nico", 
    extraInfo: {
        favFood: "KIMCHi"
    }
}
*/

// 재사용 예시
const lynn : Player<null> = {
    name: 'lynn', 
    extraInfo:null // 없어서 null 표시
}

/*
결국 여러 데이터를 가진 큰 타입에서 달라질 수 있는 값이 존재한다면, 
제네릭을 넣어서 재사용할 수 있는 것
*/

 

generic 심화2

// 제네릭 추가 
interface SStorage<T> {
    [key:string] : T
}
class LocalStorage<T> {
    private storage: SStorage<T> = {}
    set(key:string, value:T) {
        this.storage[key] = value;
    }
    remove(key:string){
        delete this.storage[key]
    }
    get(key:string):T {
        return this.storage[key]
    }
    clear(){
        this.storage = {}
    }
}
// 제네릭을 클래스로 보내고 클래스는 제네릭을 인터페이스로 보낸 뒤에 인터페이스가 제네릭을 사용하게 함
 
// localStorage을 사용하고 싶을 때 
const stringStorage = new LocalStorage<string>
stringStorage.get('xxx')      // string 받고 string return

const booleanStorage = new LocalStorage<boolean>
booleanStorage.get('xxx')     // string 받고 boolean return
반응형

'script > Typescript' 카테고리의 다른 글

TS setting  (0) 2023.01.10
Typescript 인터페이스  (0) 2023.01.09
typescript Classes(+abstract class, abstract method)  (0) 2023.01.08
Typescript call signatures, overloading  (0) 2023.01.08
Typescript의 Type 정의  (0) 2023.01.08