function helloString(message: string): string {
return message;
}
위 함수는 인자로 string 타입의 message를 받으며
return 타입도 string이다.
function helloNumber(message: number): number {
return message;
}
위 함수는 인자로 number 타입의 message를 받으며
return 타입도 number이다.
위 함수들은 각각 일정한 타입을 인자로 사용하고 return으로 받으며 반복되고 있다.
그리고 더 많은 반복이 일어날 수 있고, 반복적인 함수가 생길 수 있다.
그래서 우리는 모든 타입을 받을 수 있고 return할 수 있는 any 를 사용했다.
하지만 any를 사용하게 되면 우리의 의도와는 다르게 다른 결과를 가져온다.
function hello(message: any): any {
return message;
}
위 함수는 any를 사용한 범용적인 함수이다.
console.log(hello("hey"));
console.log(hello(30));
그렇다면 문자열, 숫자 모두 사용가능하다.
하지만, length() 라는 문자열 메서드를 사용한다고 가정해보자.
숫자형에서 length()는 사용할 수 없지만 any를 사용할 경우,
컴파일 타임에는 에러가 발생하지 않지만 런타임에는 undefined가 나올 것이다.
console.log(hello("hey").length); // 3
console.log(hello(30).length); // undefined
이런 문제를 해결하기 위해 인자로 들어가는 타입을 변수로 활용해서 return되는 타입에 연관을 시켜주면 어떨까? 이 아이디어에서 출발한 것이 generic이다.
그렇다면 제네릭을 어떻게 사용하는지 한 번 알아보자.
function helloGeneric<T>
홀화살괄호를 사용하고 Type의 T를 사용해 아래와 같이 사용한다.
function helloGeneric<T>(message: T)
message라고 받은 인자를 T라고 지정한다.
그렇게 되면 helloGeneric이라는 함수 내에서 T라고 하는 것을 기억하게 된다.
그리고 나서 예를 들어,
console.log(hello("hey"));
위 콘솔에 문자열을 넣게 되면, T가 문자열로 지정되게 된다.
function helloGeneric<T>(message: T): T {
return message;
}
그리고 return값을 T로 지정하면 된다. 즉, T의 타입에 따라 함수의 타입이 결정된다.
콘솔을 찍어보자.
console.log(helloGeneric('hey'));
그러면 helloGeneric이라는 함수는 인자가 문자열로 왔기에 리터럴 타입을 보고 문자열 리터럴 타입을 가지는 함수가 된다.
console.log(helloGeneric('hey').length);
length는 문자열의 길이 즉, 숫자형 타입을 반환하기 떄문에
콘솔을 확인하면 Number를 반환하는 것을 알 수 있다.
또한, 숫자를 넣으려고 시도하면, 자동완성기능에 숫자형 메소드를 천하고 length를 인식하지 못하는 것을 알 수 있다.
console.log(helloGeneric(30).length);
이번엔 Boolean 타입을 대입해보자.
console.log(helloGeneric(true));
인자가 boolean으로 들어가고 그에 따라 T의 타입이 Boolean, Return값 또한 boolean이 된다.
제네릭의 장점은 T를 변수처럼 사용해 타입을 지정해줄 수 있다.
any는 모든 것을 반환하고 제네릭은 지정해서 사용하는 차이점을 가진다.
any는 들어오는 input에 따라 달라지는 타이핑을 할 수 없지만 제네릭은 가능하다.