Generic(제네릭)이란?
C#이나 JAVA 등 언어에서 제네릭은 재사용성이 높은 컴포넌트를 만들때 자주 활용되는 특징이며, 한가지 타입보다 여러가지 타입에서 동작하는 컴포넌트를 생성하는데 사용된다. 타입스크립트에서 제네릭이란 타입을 마치 함수의 파라미터처럼 사용하는 것을 의미한다.
// 어떠한 타입이라도 넣을 수 있고, 그와 같은 타입으로 return 값을 지정하는 코드
function getText<T>(text: T): T { return text;}
getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
제네릭을 위 코드처럼 사용함으로서 어떤 타입이던지 복잡하게 |을 쓰지않고도 사용할 수 있다.
제네릭 타입 변수
우선 T라는 변수 타입을 받고, 인자값으로는 배열형태의 T를 받는 코드다.
예) [1,2,3]같은 배열을 받으면 반환값으로 number를 돌려줌.
function logText<T>(text: T[]): T[] {
console.log(text.length); // 제네릭 타입이 배열이기 때문에 `length`를 허용합니다.
return text;
}
// 같은 내용이지만 좀더 명시적으로 작성한 코드
function logText<T>(text: Array<T>): Array<T> {
console.log(text.length);
return text;
}
제네릭 타입 간략화
다음 #1과 #2는 같은 기능을 하는 코드다. #2가 좀더 단순화되어있다.
function logText<T>(text: T): T { return text; }
let str: <T>(text: T) => T = logText; // #1
let str: {<T>(text: T): T} = logText; // #2
이처럼 제네릭 인터페이스 코드를 다음과 같이 작성할 수 있다.
function logText<T>(text: T): T { return text; }
interface GenericLogTextFn { <T>(text: T): T; }
let myString: GenericLogTextFn = logText;
interface GenericLogTextFn<T> { (text: T): T; } // 인자타입 강조
let myString: GenericLogTextFn<string> = logText;
제네릭 클래스
제네릭 인터페이스와 비슷하게 사용하면 되는 제네릭 클래스.
단, 제네릭 클래스는 정적 측면이 아닌 인스턴스 측면에서만 제네릭이므로 클래스로 작업할때 정적 멤버는 클래스의 유형 매개변수를 사용할 수 없다.
class GenericMath<T> {
pi: T;
sum: (x: T, y: T) => T;
}
let math = new GenericMath<number>();
제네릭 제약 조건
앞에서 제네릭 타입 변수에서 살펴본 내용 말고도 제네릭 함수에 어느 정도 타입 힌트를 줄 수 있는 방법이 있다.
해당 타입을 정의하지 않고도 length 속성 정도는 허용하려면 아래와 같이 작성한다.
interface LengthWise {
length: number;
}
function logText<T extends LengthWise>(text: T): T {
console.log(text.length);
return text;
}
// Error, 숫자 타입에는 `length`가 존재하지 않으므로 오류 발생
logText(10);
// `text.length` 코드는 객체의 속성 접근과 같이 동작하므로 오류 없음
logText({ length: 0, value: 'hi' });
객체의 속성을 제약하는 방법
두 객체를 비교할 때도 제네릭 제약 조건을 사용할 수 있다.
제네릭을 선언할 때 <O extends keyof T> 부분에서 첫 번째 인자로 받는 객체에 없는 속성들은 접근할 수 없게끔 제한한 코드
function getProperty<T, O extends keyof T>(obj: T, key: O) {
return obj[key];
}
let obj = { a: 1, b: 2, c: 3 };
getProperty(obj, "a"); // okay
getProperty(obj, "z"); // error: "z"는 "a", "b", "c" 속성에 해당하지 않습니다.
참고 사이트 : 타입스크립트 핸드북
'프로그래밍 > typescsript' 카테고리의 다른 글
타입스크립트의 선언 파일 / d.ts (0) | 2022.11.23 |
---|---|
타입스크립트의 Type Aliases (타입 별칭) (0) | 2022.11.23 |
타입스크립트의 클래스 (0) | 2022.11.23 |
타입스크립트의 유니온 / 인터섹션 타입 (0) | 2022.11.23 |
타입스크립트의 Enums (이넘) (0) | 2022.11.23 |
댓글