본문 바로가기

타입스크립트

[주니어도 하는 타입스크립트] 제네릭이란 무엇이고 어떻게 쓰는것일까?

반응형

 

먼저 타입스크립트에서 예제를 통해 사용하는 일반적인 제네릭 사용법을 숙지해보자.

 

 

type User = {
    id: number;
    name: string;
    gender: number;
}

function testUser(value: any): any {
    return value;
}

function testUserInfo <T>(obj: T): T {
    return obj;
}

let test1 = testUser(10);
let test2 = testUserInfo('10');
let test3 = testUserInfo<User>({id: 1, name: '홍길동', gender: 1})

 

 

 

test1의 경우 타입이 any로 설정되었으므로 숫자 10이 들어가도 아무 문제가 없다. 대신, 숫자가 아닌 스트링이나 다른 타입이 들어가더라도 걸러지는 역할을 할 수 없다.

따라서 타입에 any를 넣을 경우 타입스크립트를 쓰나마나한 (모든 타입이 허용되는) 결과가 나온다.

 

 

반면 제네릭을 사용할 경우, 제네릭 타입이 선언되는 순간 해당 타입이 고정되어 변할 수 없는 값이 되므로 타입스크립트의 유용한 기능이라 할 수 있다.

 

제네릭으로 선언된 test2의 경우, 스트링 10이 리턴되며 스트링 외에 다른 타입으로는 반환될 수 없다.

test3은 타입 알리아스를 활용했는데, 제네릭에는 타입 유형도 선언되면서 타입 알리아스가 통째로 선언될 수도 있음을 보여준다.  User라는 타입 알리아스를 제네릭에 선언함으로써, User에 저장된 타입 유형들을 그대로 사용할 수 있음을 보여주고 있다.

 

 


class State<S, Config={}> {
    private _state: S;
    config: Config;

    constructor(state: S, config: Config) {
        this._state = state;
        this.config = config;
    }

    getState(): S {
        return this._state;
    }
}


let testState = new State<User, { active: boolean }>({
    id: 1,
    name: '홍길동',
    gender: 2
}, {
    active: true
})

 

 

이번 예제는 클래스에 제네릭을 기용했다. State라는 클래스에는 S와 오브젝트를 리턴하는 config 라는 각각의 값을 제네릭에 선언했다.

그 후 testState라는 변수에 인스턴스를 생성할 때, 위의 예제에서도 사용했던 타입알리아스 User를 S 값에, active라는 불리언 값을 갖는 오브젝트를 config={}에 적용했다.

이후 확인해보면, User에 선언한 타입 유형대로 값들은 걸러진다. 만일 타입 User에 선언된 값이 State에 선언되지 않거나, 타입을 틀리게 적는 경우 코드는 칼같이 에러를 뱉어낸다.

active가 포함된 오브젝트의 경우, 인스턴스가 생성될때 선언되었으므로 만일 불리언 타입이 아닌 다른 타입 선언을 원한다면 인스턴스 생성 시에 선언된 타입 유형을 수정하면 active를 다른 타입으로 바꿀 수 있다.

 

function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
    return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a");
getProperty(x, "m");        // m은 할당되지 않아 에러 발생


interface KeyPair<T, U> {
    key: T;
    value: U;
}
let kp: KeyPair<number, string> = { key: 1, value: 'Name' };

 

위의 예제처럼 key값을 사용해 오브젝트 안의 특정 값을 리턴할 수 있다.

getProperty라는 함수는 첫번째 인자에 오브젝트를, 두번째엔 키 값을 받도록 설정되었다. 그리고 변수 x에 다수의 오브젝트를 선언.

x변수 (오브젝트)와 'a'값을 인자로 넘기면, 값 1이 리턴된다.

하지만 'm'이라는 값은 x 오브젝트에 할당되어있지 않기 때문에, getProperty 두번째 인자로 'm' 값을 넘기면 당연히 에러가 뜬다.

 

다음은 제네릭의 인터페이스 사용법인데, 타입 알리아스와는 조금 다르므로 별도의 숙지가 필요하다.

 

이처럼 제네릭이 다양하게 쓰이고 유용하긴 하나, 사용법이 지나치게 방대하고 고급 문법이기 때문에 기본적 용법만 완벽히 숙지하는 것만으로도 충분하다.

 

 

반응형