[ TypeScript ] Generic 기초 개념
💡 Generic
이란?
대개 코딩하면서, api
를 참조할 때, 종종 다음과 같은 생소한 문법을 보았을 것이다.
function func<T1, T2>(param1: T1, param2: T2) { ... }
여기서 <T1, T2>
가 Typescript의 강력한 Generic System
이다.
쉽게 말하자면, 바로 타입에 변수를 전달하는 것이다!
좀 더 말로 쉽게 설명하자면,
T1과 T2라는 변수를 줄 건데, 이 변수는 추후, 우리가 나중에 다양한 타입으로 작성할 수 있어!
라고 말할 수 있겠다.
그렇다면 나를 비롯한 초보자는, 이런 생각이 들지도 모른다.
그렇다면, 굳이 제네릭이 any랑 다른 게 뭐야!
⭐타입 검사
이를 좀 더 찾아보았더니, 같게 쓸 수도 있고 다르게 쓸 수도 있다.
가령, 다음을 살펴보자.
다음은 같은 결과를 가져온다.
function example1<T1, T2>(a: T1, b: T2) { return [a,b] } function example2(a: any, b: any) { return [a, b] } console.log(example1('test', 1)) // ['test', 1] console.log(example2('test', 2)) // ['test', 2]
그러나 다음은, 다른 결과를 가져온다.
function example1<T1, T2>(a: T1, b: T2):T2[] { return [a,b] } // Error! (T1과 T2가 같은 유형인지 판단이 불가하므로) function example2(a: any, b: any) { return [a, b] } console.log(example1('test', 1)) // Error! console.log(example2('test', 2)) //
여기서 차이를 느낄 수 있다.
any
는 아무 유형이든 흔쾌히 받아들인다.
그러나 generic
은 두 타입이 다를 가능성을 염두한다.
결과적으로, 제네릭은 유효한 타입 검사인 것이다!
만약 위 오류를 해결하려면 다음과 같이 작성해야 할 것이다.
function example1<T1, T2>(a: T1, b: T2):(T1|T2)[] { return [a, b] }
공식문서에는 위에 관한 설명이 다음과 같이 표기되어 있다.
any를 쓰는 것은 함수의 arg가 어떤 타입이든 받을 수 있다는 점에서 제네릭이지만, 실제로 함수가 반환할 때 어떤 타입인지에 대한 정보는 잃게 됩니다. 만약 number 타입을 넘긴다고 해도 any 타입이 반환된다는 정보만 얻을 뿐입니다.
즉, 제네릭은 any
처럼 보이지만, 자신의 타입을 '지켜낸다'는 표현이 적절할 지도 모르겠다.
⭐재사용성
또한, 재사용성 역시 뛰어나다는 점 역시 제네릭의 큰 매력이다. 다음 예시를 살펴보자.
다음은 특정 배열의 인덱스를 찾아서, 원하는 값으로 업데이트해주는 함수 구현이다.
function updateArr<T>(arr:T[], target: T, replaceTo: T):T[] { const idx = arr.indexOf(target); arr[idx] = replaceTo; return arr; } console.log(updateArr([1,2,3,4], 4, 999)) // [1,2,3,999]
이를 실제로 구현하려면, 제네릭이 아닌 경우는 any를 사용해야 한다.
다음을 보자.
function updateArr2<T>(arr:any, target: any, replaceTo: any):any[] { const idx = arr.indexOf(target); arr[idx] = replaceTo; return arr; } console.log(updateArr([1,2,3,4], 4, 999))// [1,2,3,999]
잘 작동하지 않아서 좋지 않나요?!라는 생각이 들 정도로, 잘 된다.
그러나, 다음을 명령하면 결과는 어떨까?
console.log(updateArr([1,2,3,4], '4', 999)) // Error checked! console.log(updateArr2([1,2,3,4], '4', 999)) //[ 1, 2, 3, 4, '-1': 999 ]
결과적으로 전자는 위의 케이스에 대하여 타입 검사를 제대로 했지만, 후자는 타입 검사를 통해 오류를 처리하지 못하고 있다.
💬 정리하며
타입스크립트의 궁극적인 목적은, 유효한 타입인지를 검사하여 사전에 오류를 빠르게 체크하기 위한 것이다.
이러한 측면에서 볼 때, 제네릭이 특정 타입을 지켜내고 싶을 때,
any
보다, 타입 검사를 더욱 우수하게 할 수 있음을 알 수 있으며,- 특정 타입을 추가로 입력하지 않고 들어오는 값에 따라 설정되기에 재사용성이 높다 :)
Author And Source
이 문제에 관하여([ TypeScript ] Generic 기초 개념), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jengyoung/TypeScript-Generics-기초-개념저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)