타입스크립트 기초 제네릭 클래스 / 클래스 구조 재사용

타입스크립트 제네릭 클래스( TypeScript Generic Class)는
클래스 이름 뒤에 <T>와 같은 타입 매개변수를 선언하여
하나의 클래스 구조를 여러 데이터 타입에 재사용하는 방법이다.

class Box<T>처럼 클래스를 만든 뒤 Box<number>, Box<string>처럼 사용할 수 있다.

중복 클래스를 여러 개 만들 필요가 없으며, 재사용 가능한 코드를 작성할 수 있으며,
<T>를 임시로 표시하는 이름 정도로 볼 수 있다.

타입스크립트 기초 제네릭 클래스  <T> 사용 클래스 구조 재사용
타입스크립트 기초 제네릭 클래스 <T> 사용 클래스 구조 재사용

⊙ 타입스크립트 제네릭 클래스

타입스크립트( Typescript )의 제네릭(Generic)은 타입을 매개변수처럼 전달하는 기능이다.

만약, 일반 클래스를 만들고, 타입을 number로 설정하면 숫자만 사용할 수 있다.

class NumberBox {
  value: number;

  constructor(value: number) {
    this.value = value;
  }
}

위의 코드는 숫자만 가능하며, 문자열을 저장하려면 별도의 클래스를 만들어야 한다.

제네릭을 사용하면 하나의 클래스로 해결할 수 있다.

class Box<T> {
  value: T;

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

위의 코드에서 T는 타입 매개변수(Type Parameter)이다.

쉽개 비유하면
T는 아직 내용물이 정해지지 않은 상자에 붙여 놓은 빈 라벨이라고 생각하자.

타입스크립트 제네릭 클래스
타입스크립트 제네릭 클래스

⊙제네릭 클래스 기본 문법

타입스크립트에서 사용하는 제네릭 클래스의 기본 문법은 다음과 같다.

클래스, 생성자, 메서드에 제네릭을 표시하는 <T>와 T를 설정했다.

class Box<T> {
  value: T;

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

  getValue(): T {
    return this.value;
  }
}

핵심은 세 곳이다.

class Box<T>

<T>는 이 클래스에서 사용할 타입을 나타낸다.

value: T

value의 타입을 T로 지정한다.

getValue(): T

메서드가 반환하는 값도 같은 T 타입이다.

만약,
Box<number>를 만들면 클래스 내부의 T는 number가 되고,
Box<string>을 만들면 T는 string이 된다.

타입스크립트의 제네릭 클래스는 클래스 이름 뒤의 꺾쇠괄호 <> 안에 타입 매개변수를 선언하는 형태이다.

제네릭 클래스 기본 문법
제네릭 클래스 기본 문법

⊙ 제네릭 클래스 number와 string 사용

제네릭 클래스가 무엇인지, 사용법을 알았다.

단순히 클래스의 껍데기 정도로 생각하자.

제네릭 클래스를 사용하면 어떤 타입이든 공통된 형식의 클래스를 여러 개로 사용할 수 있다.

이번엔 하나의 제네릭 클래스를 사용하여 number, string 타입을 사용해 보기로 한다.

class Box<T> {
  value: T;

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

  getValue(): T {
    return this.value;
  }
}

const numberBox = new Box<number>(100);
const stringBox = new Box<string>("Hello");

console.log(numberBox.getValue());
console.log(stringBox.getValue());

제네릭 클래스 하나를 만들었지만,
전혀 다른 타입의 클래스로 사용할 수 있다.

위의 코드에서 제네릭 T 가 설정된 부분이 중요하며, T를 선언하는 방법에 따라 타입이 결정된다.

위의 결과에 대한 실행 결과는 다음과 같다.

제네릭 클래스 number와 string 사용
제네릭 클래스 number와 string 사용
제네릭 클래스 number와 string 사용
제네릭 클래스 number와 string 사용

⊙ 객체를 저장하는 제네릭 클래스 만들기

타입스크립트 제네릭 클래스는 숫자와 문자열뿐 아니라 객체 타입도 사용하여 객체 타입 데이터를 저장하여 사용할 수 있다.

코드를 보자.

class StorageBox<T> {
  private items: T[] = [];

  add(item: T): void {
    this.items.push(item);
  }

  getAll(): T[] {
    return this.items;
  }
}

객체 저장을 위한 제네릭 클래스의 사용법은 동일하다.

사용할 객체 타입을 만들어 보자.

interface User {
  id: number;
  name: string;
}

const userStorage = new StorageBox<User>();

userStorage.add({
  id: 1,
  name: "Kim"
});

userStorage.add({
  id: 2,
  name: "Lee"
});

console.log(userStorage.getAll());

StorageBox<User>를 선언하는 순간 클래스의 제네릭 T는 User가 된다.

다만, 제네릭 클래스에 저장되는 객체의 형태는 같아야 하며,
다음처럼 구조가 다른 경우 타입 검사에서 오류가 발생한다.

userStorage.add({
  id: 3
});

User 타입에 필요한 name이 없으며, 객체의 구조가 다르기에 타입 검사에서 오류가 발생한다.

객체를 저장하는 제네릭 클래스 만들기
객체를 저장하는 제네릭 클래스 만들기

⊙ extends 제네렉 타입 제한하기

타입스크립트 제네릭에 extends 키워드를 사용하면 타입을 제한할 수 있다.

이 기능은 다른 의미로 제네릭 제약조건( Generic Constraints )이라 한다.

타입스크립트 제네릭의 extends 는 클래스 내부에서 특정 프로퍼티나 메서드를 반드시 사용해야 할 때 유용하다.

코드를 보자.

interface HasId {
  id: number;
}

class Repository<T extends HasId> {
  private items: T[] = [];

  add(item: T): void {
    this.items.push(item);
  }

  findById(id: number): T | undefined {
    return this.items.find(item => item.id === id);
  }
}

위의 코드를 보면, 이제 제너릭 T에는 최소한 다음의 구조가 존재해야 한다.

{
  id: number;
}

id 타입이 있는 다른 구조를 만들어 보자.

최소한의 구조에 id 가 있으며, 제네릭 클래스로 사용할 수 있다.

interface Product {
  id: number;
  name: string;
  price: number;
}

const products = new Repository<Product>();

만약, id가 없는 타입은 제약조건을 만족하지 못하며, 타입 검증 단계에서 에러가 발생한다.

extends 제네렉 타입 제한
extends 제네렉 타입 제한

⊙ 제네릭 클래스 주의할 점

타입스크립트의 제네릭을 뜻하는 단어 <T>의 T는 특별한 키워드는 아니다.

임의의 단어 또는 자신이 원하는 단어를 사용할 수도 있다.

아래의 코드를 보자.

본래의 경우 <T> 형태로 제네릭 클래스를 지정해야 되지만 <Type> 형태의 단어를 사용했다.

그럼에도 타입스크립트 제네릭을 사용하는데 문제는 없다.

class Box<Type> {
  value: Type;

  constructor(value: Type) {
    this.value = value;
  }
}

타입스크립트 제네릭에서 <T>의 T라는 단어는
T, Type, Item처럼 의미에 맞는 이름을 사용할 수 있다.

클래스의 static 멤버에서 클래스 타입 매개변수를 직접 사용할 수 없다.

다음 코드는 허용되지 않는다.

class Box<T> {
  static defaultValue: T;
}

제네릭 클래스의 클래스 타입 매개변수 자체는 인스턴스이며,
정적 멤버는 해당 클래스 타입 매개변수를 참조할 수 없다.

난해하다면, 단순히 아래의 코드 형태를 눈으로 익혀두도록 한다.

class Box<T> {
  constructor(public value: T) {}
}

const a = new Box<number>(100);
const b = new Box<string>("Hello");
제네릭 클래스 주의할 점
제네릭 클래스 주의할 점

댓글

비주얼 스튜디오 코드 VSCode 설치하기 - 마이크로소프트 공식 홈페이지

이미지
VSCode( 비주얼스튜디오코드, Visual Studio Code )는 마이크로소프트( Microsoft )에서 제공하는 있는 무료 코드 편집기 프로그램이다. 프로그래밍 언어의 소스 코드를 작성하고 수정하며, 확장 기능을 설치하여 개발 환경을 구성할 수 있다. 윈도우즈, 맥OS, 리눅스( Windows, macOS, Linux )에서 사용할 수 있으며, 공식 홈페이지를 통해 자신의 운영체제에 맞는 설치 파일을 다운로드받고 설치할 수 있다. 윈도우즈의 경우, 인스톨러 파일( Installer )를 이용하여 설치할 수 있다. 설치파일을 다운로드하고 실행한 다음 화면의 안내에 따라 VSCode 설치를 진행하면 된다. 설치가 완료되면 VSCode를 실행하여 자신이 원하는 코드를 작성할 수 있다. 비주얼 스튜디오 코드 설치하기 - 마이크로소프트 공식 홈페이지 VSCode 무료 소스 코드 편집기 VSCode(비주얼 스튜디오 코드, Visual Studio Code)는 Microsoft에서 개발한 무료 소스 코드 편집기이다. 소스 코드란 컴퓨터 프로그램을 만들기 위해 프로그래밍 언어로 작성한 명령문의 집합이며, VSCode에서 소스 코드를 작성하고 수정할 수 있다. VSCode의 특징을 보자. 무료 사용 VSCode 기본 프로그램을 무료로 다운로드하여 사용 다중 운영체제 Windows, macOS, Linux를 지원 코드 편집 여러 프로그래밍 언어의 소스 코드를 작성하고 수정 가능 확장 기능 Extensions를 이용하여 언어 지원과 개발 도구를 추가 디버깅 지원되는 언어와 개발 환경에서 프로그램 오류를 조사 Git 통합 Git을 이용한 소스 코드 변경 관리 기능을 제공 VSCode 자체는 코드 편집기이고 프로그래밍 언어에 따라 컴파일러, 실행 환경, 개발 도구 등을 별도로 설치해야 할 필요가 있다. 만약, Java 프로그램을 개발할 때는 VSCode 외에 JDK와 관련 확장 기능이 필요하다. VSCode 무료 소스 코드 편집기 VSCode 설치 전 확인 사항 VSCo...

이 블로그의 인기 게시물

ChatGPT Codex GitHub 연결 해제 방법 (앱 삭제까지 정리)

C언어 return 종류와 차이 | return, return 0, return -1, return n

C언어 프로그램 종료 방법 3가지 비교 (실전 예제 포함) | exit() abort() 함수 사용 방법