본문 바로가기

타입스크립트

[TypeScript] - 제네릭

 

제네릭이란 ?

 

제네릭이란 타입을 마치 함수의 파라미터 처럼 사용하는 것을 의미한다.

 

 

위 함수는 text 라는 파라미터에 값을 넘겨 받아 text를 반환해준다 'hi' 10 true 등 어떤 값이 들어가더라도 그대로 반환한다 

 

 

이 관점에서 제네릭을 살펴보면 위 함수는 제네릭 기본 문법이 적용된 형태이다 이제 함수를 호출할 때 아래와 같이 함수 안에서 사용할 타입을 넘겨 줄 수 있다.

 

 

위 코드 중 getText<string>('hi') 를 호출할 때 함수에서 제네릭이 어떻게 동작하는지 살펴보면 

 

 

위 함수에서 제네릭 타입이 <string>이 되는 이유는 getText()함수를 호출할 때 제네릭 값으로 string을 넘겼기 때문이다 

 

 

제네릭을 사용하는 이유 

 

 

위 코드는 인자를 하나 넘겨 받아 반환해주는 함수이다 여기서 인자와 반환 값을 모두 string 으로 저장되어 있지만 만약 여러가지 타입을 허용하고 싶다면 any 를 사용할 수도 있다 .

 

 

위위 코드 처럼 타입을 바꾼다고 해서 함수의 동작에 문제가 생기지는 않는다 다만 함수의 인자로 어떤 타입이 들어갔고 어떤 값이 반환되는지 알 수가 없다 왜냐하면 any라는 타입은 타입검사를 하지 않기 때문이다 

 

이러한 문제점을 해결할 수 있는 것이 제네릭이다.

 

 

함수 앞에 <T> 라는 코드를 추가했다 그리고 함수의 ㅇ니자와 반환 값에 모두 T 라는 타입을 추가했다 이렇게 되면 함수를 호출할 때 넘긴 타입에 대해 타입스크립트가 추정할 수 있게 된다 따라서 함수의 입력 값에 대핸 타입과 출력 값에 대한 타입이 동일 한지 검증 할 수 있다. 이렇게 선언한 함수는 아래와 같이 2가지 방법으로 호출 할 수 있다.

 

 

 

보통 두번째 방법이 코드도 더 짧고 가독성이 좋기 때문에 흔하게 사용된다 하지만 만약 복잡한 코드에서 두번째 코드로 타입 추정이 되지 않는 다면 첫번째 방법을 사용하면 된다 .

 

제네릭 타입 변수 

 

 

위 코드를 변환 하려고 하면 컴파일러에서 에러를 발생시킨다 왜냐하면 text에 length 가 있다는 단서는 어디에도 없기 때문이다 다시 위 제네릭 코드의 의미를 살펴보면 함수의 인자와 반환 값에 대한 타입을 정하지 않았지만 입력 값으로 어떤 타입이 들어왔고 반환 값으로 어떤 타입이 나가는지 알 수 있다.

 

따라서 함수의 인자와 반환 값 타입에 마치 any 를 지정한 것과 같은 동작은 한다는 것을 알 수 있다 그래서 설령 인자에 Number 타입을 넘기더라도 에러가 나지 않는다  이러한 특성 때문에 현재 인자인 text에 문자열이나 배열이 들어와도 컴파일러 입장에서는 length 를 허용할 수 없다.

 

 

이와 같은 경우 위의 코드처럼 제네릭에 타입을 줄 수가 있습니다 기존의 제네릭 코드와 다른 점은 인자의 T[] 부분이다 제네릭 함수 코드는 일단 T 라는 변수 타입을 받고 인자 값으로는 배열 형태의 T[] 를 받습니다 예를 들면 함수에 [1,2,3] CJ처럼 숫자로 이뤄진 배열을 받으면 반환 값으로 number를 돌려줍니다.

 

이이런 방식으로 제네릭을 사용하면 꽤 유연한 방식으로 함수의 타입을 정의해 줄 수 있습니다.

 

 

혹은 위 코드처럼 좀 더 명시적으로 제네릭 타입을 선언 할 수도 있다.

 

제네릭 인터페이스 

 

 

제네릭 인터페이스에 대해 알아보면 위에 두 코드는 같은 의미이다 .

 

위와 같은 변형 방식으로 제네릭 인터페이스 코드를 다음과 같이 작성 할 수 있다.

 

 

위 코드에서 만약 인터페이스 인자 타입을 강조하고 싶다면 아래와 같이 변형 할 수 있다.

 

제네릭 클래스 

 

 

제네릭 클래스는 제네릭 인터페이스와 거의 비슷하다 

제네릭 클래스를 선언할 때 클래스 이름 오른쪽에 <T> 를 붙여준다 그리고 해당 클래스로 인스턴스를 생성할때마다 타입에 어떤 값이 들어갈지 지정하면 된다.