가만보면,,, 프로그래밍 전체로 생각하기에는 내 앎이 굉장히 좁기에 단정지을 수 없지만,,, 적어도 자바스크립트는 하드코딩을 엄청엄청 싫어하는 것 같다.
1. 타입스크립트의 제네릭 (Generic)
공식문서에 따르면, 제네릭이란 타입을 마치 함수의 파라미터처럼 사용하는 것을 의미한다고 한다.
제네릭이 타입스크립트 내부에서 동작하는 원리는 TypeScript 컴파일러가 컴파일하는 과정에서 타입 추론에 활용됨으로 코드의 재사용성 및 안정성을 높이기 위해 사용된다.
function getText<T>(text: T): T {
return text;
}
// 이 코드는 다음과 같은 익숙한 자바스크립트 함수에 새로운 제네릭 타입 <T>를 선언한 구문이다.
function getText [제네릭이 삽입된 부분] {
return text;
}
그렇다면 제네릭이 삽입된 부분에 해당하는 구문을 분석해보고자 한다.
<T>
➡️ 꺽쇠괄호 안에 변수 T를 담아 새로운 타입 T를 선언한다.
(text : T)
➡️ text의 타입이 T 타입임을 정의한다.
: T
➡️ 함수가 받은 인자와 동일한 타입을 리턴한다는 것을 나타낸다.
이 구문은 상당히 편하게 제네릭을 이해할 수 있는 구문이지만, text와 변수 T의 관계를 유추해내기는 어렵다.
다음의 구문을 통해 좀 더 깊이 살펴보고자 한다.
function getText<T>(text: T): number {
return text.length;
}
<T>
➡️ 꺽쇠괄호 안에 변수 T를 담아 새로운 타입 T를 선언한다.
(text : T)
➡️ text의 타입이 T 타입임을 정의한다.
: number
➡️ 함수가 리턴하는 타입이 number 타입임을 정의한다
2. 제네릭 인터페이스 / 제네릭 클래스
제네릭은 한 변수나 함수의 타입을 정의할 뿐 아니라, 특정한 클래스와 인터페이스(객체 타입)을 정의하는데도 사용할 수 있다.
// 제네릭 인터페이스
interface GenericLogTextFn {
<T>(text: T): T;
}
function logText<T>(text: T): T {
return text;
}
let myString: GenericLogTextFn = logText; // Okay
위 구문에서 3가지를 체크할 수 있다.
GenericLogTextFn
➡️ text의 타입은 T인, 인터페이스 선언
logText 함수
➡️ text의 타입이 T인 리턴 값을 추론할 수 있는 함수
myString 변수
➡️ myString 변수의 타입은 GenericLogTextFn, logText의 정의된 T변수가 text와 같은 타입임을 추론할 수 있음으로 참이다.
➡️ 만약, text와 다른 타입의 값이 리턴될 경우 TS는 에러를 던진다.
이처럼, 제네릭 타입은 인터페이스에서 선언된 그대로 마치 인자처럼 함수 내에서 추론이 가능케한다.
// 제네릭 클래스의 활용
class GenericMath<T> {
pi: T;
sum: (x: T, y: T) => T;
}
let math = new GenericMath<number>();
위 구문에서도 3가지를 체크할 수 있다.
pi: T
➡️ pi 속성이 T타입으로 정의되었다.
sum: (x: T, y: T) => T;
➡️ sum 속성은 x, y를 인자로 받는데 두 인자 모두 T타입이며, 이 구문의 결과 또한 T타입으로 추론한다.
let math = new GenericMath<number>();
➡️ 새롭게 정의된 math 인스턴스는 GenericMath 생성자에서 만들어진 인스턴스이며, 이는 <number>타입임을 추론할 수 있다.
➡️ 만약, math에 정의되지 않은 타입의 인자(문자열, 불리언 등)가 전달될 경우 TS는 에러를 던진다.
제네릭의 본질은 타입스크립트의 본질인 "타입검사"를 동일한 변수를 사용하는 여러 식에 적용함으로써, 사용성이 높은 컴포넌트를 만들 때 타입 일반화를 통해 코드의 재사용성을 높이는 데 사용된다.
공식문서 링크 : https://joshua1988.github.io/ts/guide/generics.html
'프로그래밍 언어 > Typescript' 카테고리의 다른 글
Typescript 개요 (0) | 2023.03.29 |
---|