제너릭 - Class (2)

Changhan·2025년 2월 14일

Typescript

목록 보기
29/29

메소드에서의 제너릭

class DuplicatedGenericName<T> {
  sayHello<T>(logTime: T) {
    console.log(`logTime: ${typeof logTime}`);
  }
}
const duplicated = new DuplicatedGenericName<string>(); // 클래스의 제너릭은 string
duplicated.sayHello<number>(123); // 메서드는 number

클래스의 제너릭과 메서드의 제너릭이 동시에 같은 이름으로 선언이 되면 메서드의 제너릭을 따라간다. 즉 DuplicatedGenericName의 T는 어디에서도 쓰이지 않는다.
따라서 헷갈리지 않도록 클래스 제너릭과 메서드 제너릭의 이름을 서로 다르게 선언하자.

implementation에서의 제너릭

interface Singer<T, V> {
  name: T;
  sing(year: V): void;
}

// #1
// Singer을 implement 했기 때문에 class 안데 Singer의 프로퍼티, 메소드들이 다 존재해야 한다.
class Idol implements Singer<string, number> {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  sing(year: number): void {
    console.log(`${year} ${this.name}이 노래를 부른다.`);
  }
}
const yujin = new Idol('안유진');
yujin.sing(2003);

Idole 클래스는 Singer 타입을 implement 했기 때문에 Singer의 프로퍼티와 함수가 Idol에 존재해야 한다.

위처럼 인터페이스에 제너릭 타입을 줄 수도 있고, 아래처럼 인스턴스를 생성할 때 제너릭 타입을 줄 수 있다.

class Idol2<T, V> implements Singer<T, V> {
  name: T;

  constructor(name: T) {
    this.name = name;
  }

  sing(year: V): void {
    console.log(`${year} ${this.name}이 노래를 부른다.`);
  }
}
const yuna = new Idol2<string, number>('윤아');
yuna.sing(1990);

Promise에서의 제너릭

가장 많이 사용하게 될 방식 중 하나다.

const afterTwoSeconds = function () {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('done');
    }, 2000);
  });
};
const runner = async function () {
  const res = await afterTwoSeconds(); // unknown 타입이 나옴, 좀 불쾌함. resolve에서 'done'이라는 string을 받게 하고 싶다.
  console.log(res);
};
runner();

afterTwoSeconds 함수는 2초 뒤에 'done' 문자열을 출력하는 Promise를 반환한다. 하지만 runner에서 비동기적으로 실행하면 afterTwoSeconds 함수는 unknown 타입을 리턴한다. 우리가 원하는 타입을 리턴하려면 어떻게 해야 할까?

const afterOneSecond = function (): Promise<string> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('done');
    }, 1000);
  });
};
const runner2 = async function () {
  const res = await afterOneSecond(); // type: string
  console.log(res);
};
runner2();

Promise 타입에 제너릭 타입을 우리가 원하는 타입을 주면 된다.

0개의 댓글