Generics

장유진·2022년 6월 28일
1

TypeScript

목록 보기
10/14

https://www.typescriptlang.org/docs/handbook/generics.html

generic은 재사용 가능한 요소들을 생성하기 위한 도구이다. 한 가지 타입보다는 여러 가지 타입으로 사용가능하게 만들어 다양하게 쓸 수 있다.

Hello World of Generics

generic의 기본은 identity function이다. identity function은 전달받은 것을 그대로 다시 반환하는 함수이다. generic을 사용할 때에는 <> 안에 타입을 넣어 사용하면 된다.

function identity<T>(arg: T): T {
  return arg;
}

let output = identity<string>("myString");
let output = identity("myString");

위 예제에서 타입을 직접 설정하여 사용해도 되지만, TypeScript는 parameter의 타입을 추론할 수 있기때문에 생략해도 무방하다.

Working with Generic Type Variables

generic 타입의 변수를 사용할 때에는 해당 변수가 모든 타입이 될 수 있음을 감안해야 한다. 즉, 해당 변수가 가질 수 있는 속성이 무엇인지 주의하여 사용하여야 한다. 아래 예제에서는 모든 타입이 length라는 속성을 가지고 있지 않아 arg가 length라는 속성을 가진다는 보장이 없기 때문에 오류가 발생한다.

function loggingIdentity<T>(arg: T): T {
  console.log(arg.length);
Property 'length' does not exist on type 'T'.
  return arg;
}

Generic Types

generic function의 함수 타입은 다른 일반 함수 타입과 형식이 같다. generic function 타입의 parameter에서 타입의 수와 순서가 같다면 타입의 이름은 달라도 된다. 또한 generic type을 call signavure처럼 쓸 수도 있고 따라서 interface로도 사용이 가능하다. interface로 사용할 때에는 타입이 interface 이름에 나타나거나 안 나타나도록 할 수 있다.

function identity<T>(arg: T): T {
  return arg;
}
interface GenericIdentityFn {
  <T>(arg: T): T;
}
interface GenericIdentityFn<T> {
  (arg: T): T;
}

let myIdentity1: <T>(arg: T) => T = identity;
let myIdentity2: <U>(arg: U) => U = identity;
let myIdentity3: { <T>(arg: T): T } = identity;
let myIdentity4: GenericIdentityFn = identity;
let myIdentity5: GenericIdentityFn<number> = identity;

Generic Classes

generic class는 클래스 이름 뒤에 <>를 붙여 사용한다.
클래스의 instance 멤버만이 generic할 수 있고 static 멤버들은 generic하지 못한다. 따라서 static 멤버들은 클래스의 타입 파라미터를 사용할 수 없다.

class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
  return x + y;
};

Generic Constraints

generic을 사용할 때에는 모든 타입의 변수가 해당 속성을 가지고 있는지 주의하고 사용해야 한다고 했다. 하지만 interface를 상속하도록 사용하면 generic 함수가 특정 속성을 가진 타입만 사용하도록 제한을 둘 수 있다.

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}

loggingIdentity({ length: 10, value: 3 });
profile
프론트엔드 개발자

0개의 댓글