Typescript Generics

Jinmin Kim·2023년 7월 5일

제네릭

param

function logText<T>(text: T): T {
  return text;
}

// #1
const text = logText<string>("Hello Generic");
// #2
const text = logText("Hello Generic");

array param

function logText<T>(text: T[]): T[] {
  console.log(text.length); // 제네릭 타입이 배열이기 때문에 `length`를 허용합니다.
  return text;
}

interface

interface GenericLogTextFn<T> {
  (text: T): T;
}
function logText<T>(text: T): T {
  return text;
}
let myString: GenericLogTextFn<string> = logText;

class

class GenericMath<T> {
  pi: T;
  sum: (x: T, y: T) => T;
}

let math = new GenericMath<number>();

타입 호환

Enum 타입 호환 주의 사항

이넘 타입은 number 타입과 호환되지만 이넘 타입끼리는 호환되지 않습니다.

enum Status { Ready, Waiting };
enum Color { Red, Blue, Green };

let status = Status.Ready;
status = Color.Green;  // Error

Class 타입 호환 주의 사항

클래스 타입은 클래스 타입끼리 비교할 때 스태틱 멤버(static member)와 생성자(constructor)를 제외하고 속성만 비교합니다.

class Hulk {
  handSize: number;
  constructor(name: string, numHand: number) { }
}

class Captain {
  handSize: number;
  constructor(numHand: number) { }
}

let a: Hulk;
let s: Captain;

a = s;  // OK
s = a;  // OK

Generics

제네릭은 제네릭 타입 간의 호환 여부를 판단할 때 타입 인자 가 속성에 할당 되었는지를 기준으로 합니다. 예시 코드를 보겠습니다.

interface Empty<T> {
}
let x: Empty<number>;
let y: Empty<string>;

x = y;  // OK, because y matches structure of x
위 인터페이스는 일단 속성(member 변수)이 없기 때문에 x와 y는 같은 타입으로 간주됩니다. 
그런데 만약 아래와 같이 인터페이스에 속성이 있어서 제네릭의 타입 인자가 속성에 할당된다면 
얘기는 다릅니다.

interface NotEmpty<T> {
  data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;

x = y;  // Error, because x and y are not compatible
인터페이스 NotEmpty에 넘긴 제네릭 타입<T>이 data 속성에 할당되었으므로 
x와 y는 서로 다른 타입으로 간주됩니다.

** 출처
https://joshua1988.github.io/ts/guide/type-compatibility.html#generics

profile
Let's do it developer

0개의 댓글