본문 바로가기

JS&TS Essential/TypeScript

Generic

오늘은 TypeScript에서 Generic을 어떻게 사용하는지에 대해 알아보겠다.
Genric은 단일 타입이 아닌 다양한 타입에서 작동하는 function, class, interface를 만들 때 사용된다.

간단히 다음 예시를 살펴보자!

 

function printValGeneric<T>(val: T): T {
    console.log(val);
    return val;
}

const a = printValGeneric<string>('hi');
const a2 = printValGeneric('hi');

 

'printValGeneric' 함수는 입력받은 값을 출력 및 반환하는 함수이다.
먼저 문법부터 살펴보면 함수를 선언할 때 'T'라는 타입변수를 <>로 감싸서 입력받고 있다.

또한 'T' 타입의 인수 'val'을 입력받고 있고, 반환 타입도 'T' 타입이다.

'T'는 타입변수이고, 입력받아야 하기때문에 함수가 호출되기 전까지는 무엇이 될지 알 수 없다.

타입변수 'T'는 타입이 사용될 수 있는 곳 어디서나 사용가능하다.

이렇게 Generic은 다양한 타입에서 함수가 동작할 수 있게 해주는 기능이다.

 

함수를 호출할 때는 <> 사이에 Type 인수를 입력해주거나

생략도 가능한데, 생략할 경우 타입 추론이 이루어지게 된다.

printValGeneric 함수의 명세에 따라 Type 변수로 string을 보냈을 때
반환값으로 string type을 가지게 된다. a의 type이 string인 것도 확인할 수 있다.

 


any와 genric의 차이점

function printVal(val: any): any {
    console.log(val);
    return val;
}

const b = printVal('h1');

 

'printVal' 함수에서 입력받는 인자의 타입으로 any를 주고 있다.

따라서 해당 함수는 모든 타입에서 동작가능하다. 이 부분은 Genric과 동일하다.

하지만 함수가 return될 때 타입에 대한 정보를 잃게 된다.

Generic을 사용할 때는 string을 넣고 string type의 변수를 반환받을 수 있었지만,

Any를 사용할 때는 어떤 type을 넣든 any type만을 반환받게 된다.

 

Generic을 사용하지 않은 printVal에서는 반환타입이 any로 고정되는 것을 알 수 있다.

Generic과 any의 뚜렷한 차이점 중 하나는 Type 보관 가능유무이다.

 


interface Animal {
    species: string;
    name: string;
    age: number;
    signature(): string;
}

function printInfo<T extends Animal>(animal: T) {
    console.log(`${animal.species} ${animal.name}'s signature is ${animal.signature()}`);
}

printInfo({
    species: 'dolphin',
    name: 'doli',
    age: 20,
    signature: () => 'swimming'
});

printInfo({
    species: 'horse',
    name: 'hori',
    age: 20,
    signature: () => 'running'
});

 

Generic 기능을 통해 입력받을 Type 변수를 제한할 수도 있다.

printInfo 타입변수 'T'는 'Animal'을 상속받은 타입만 들어올 수 있게 제한되어 있다.

이에 따라 printInfo의 인자 'animal'은 Animal interface의 속성과 함수들을 모두 사용할 수 있다.

 

 


Lambda로 Generic 사용하기

const printValGeneric = <T>(val: :T): T => {
	console.log(val);
	return val;
}

 

Generic을 lambda에서 사용할 때는 인자를 입력받기 전에 Type변수를 입력받도록 코드를 작성하면 된다.

 

 

Generic에서는 Type 변수를 여러 개 입력받을 수도 있고, keyof를 이용해서 타입을 제한할 수도 있다.

Generic을 이용해 생성자를 입력받을 때 타입을 제한할 수도 있다.

이외에도 내가 모르는 많은 기능들이 있을테니, 열심히 공부하도록 하자!

'JS&TS Essential > TypeScript' 카테고리의 다른 글

Vue에서 TypeScript 사용하기: Props  (0) 2021.03.06
TypeScript: Generic  (0) 2021.03.06
Vue에서 TypeScript 사용하기: Data  (0) 2021.03.04