FRONTMANFRONTMAN
  • 태그
  • 방명록
  • 글쓰기
  • 관리자
  • HOME
  • 태그
  • 방명록
TypeScript 제네릭(Generics)
hahekaku
TypeScript 제네릭(Generics)Language/TypeScript2023. 10. 16. 22:07@hahekaku
Table of Contents

제네릭의 개념과 필요성

제네릭(Generics)는 TypeScript에서 코드 재사용성을 극대화하고 타입 안정성을 보장하는 데 매우 유용한 도구입니다. 제네릭을 사용하면 함수, 클래스, 인터페이스를 다양한 타입으로 처리할 수 있습니다.

필요성

일반적으로 함수나 클래스에서 특정 타입을 다루게 되면, 그 타입이 고정적이어서 재사용성이 떨어집니다. 제네릭은 이러한 문제를 해결하고 다양한 타입을 지원할 수 있도록 설계되었습니다.

예를 들어, 배열의 첫 번째 요소를 반환하는 함수를 생각해 봅시다.

// 문자열 배열에 대해 동작하는 함수
function getFirstElementString(arr: string[]): string {
  return arr[0];
}

// 숫자 배열에 대해 동작하는 함수
function getFirstElementNumber(arr: number[]): number {
  return arr[0];
}

위의 코드는 문자열과 숫자 배열 각각에 대해 별도의 함수를 작성해야 하므로 비효율적입니다. 제네릭을 사용하면 이러한 중복 코드를 줄일 수 있습니다.


제네릭 함수와 클래스 정의

제네릭 함수

제네릭 함수는 타입을 함수 호출 시점에 정의할 수 있습니다. 타입 매개변수는 대개 T로 표기되며, 이는 관습적인 이름일 뿐 다른 이름을 사용해도 무방합니다.

예제: 배열의 첫 번째 요소 반환

function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

const stringArray = ['apple', 'banana', 'cherry'];
const numberArray = [1, 2, 3, 4];

const firstString = getFirstElement(stringArray); // 'apple'
const firstNumber = getFirstElement(numberArray); // 1

이 함수는 배열의 타입에 관계없이 재사용할 수 있으며, 타입 추론 덕분에 호출 시 타입을 명시하지 않아도 됩니다.


제네릭 클래스

제네릭은 클래스에서도 사용 가능합니다. 예를 들어, 데이터를 저장하고 관리하는 상자를 만드는 클래스를 생각해봅시다.

예제: 제네릭 클래스를 활용한 데이터 저장소

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

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

  removeItem(item: T): void {
    this.items = this.items.filter(storedItem => storedItem !== item);
  }

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

const stringStorage = new DataStorage<string>();
stringStorage.addItem('Book');
stringStorage.addItem('Pen');
stringStorage.removeItem('Pen');
console.log(stringStorage.getItems()); // ['Book']

const numberStorage = new DataStorage<number>();
numberStorage.addItem(42);
numberStorage.addItem(7);
numberStorage.removeItem(42);
console.log(numberStorage.getItems()); // [7]

제네릭 제약조건(Constraints) 설정

제네릭은 기본적으로 어떤 타입이든 사용할 수 있지만, 때로는 특정 타입이나 타입의 특징을 강제해야 할 필요가 있습니다. 이때 extends 키워드를 사용하여 제약조건을 설정할 수 있습니다.

예제: 객체의 특정 속성에 접근

다음은 객체 배열에서 특정 키의 값을 추출하는 함수입니다.

interface Person {
  name: string;
  age: number;
}

function extractProperty<T extends object, K extends keyof T>(items: T[], key: K): T[K][] {
  return items.map(item => item[key]);
}

const people: Person[] = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 },
];

const names = extractProperty(people, 'name'); // ['Alice', 'Bob']
const ages = extractProperty(people, 'age'); // [30, 25]

설명

  • T extends object: T는 객체 타입이어야 합니다.
  • K extends keyof T: K는 T의 키 중 하나여야 합니다.

제약조건을 사용한 정렬 함수

객체 배열을 특정 키를 기준으로 정렬하는 예제입니다.

function sortBy<T extends object, K extends keyof T>(items: T[], key: K): T[] {
  return [...items].sort((a, b) => {
    if (a[key] < b[key]) return -1;
    if (a[key] > b[key]) return 1;
    return 0;
  });
}

const sortedPeople = sortBy(people, 'age');
console.log(sortedPeople);
// [{ name: 'Bob', age: 25 }, { name: 'Alice', age: 30 }]

기본 타입 설정

제네릭 타입 매개변수에 기본 타입을 설정할 수도 있습니다.

예제: 기본 타입이 string인 함수

function logItem<T = string>(item: T): void {
  console.log(item);
}

logItem('Hello'); // 'Hello'
logItem(123); // 123

결론

제네릭(Generics)은 타입 안정성과 코드 재사용성을 크게 향상시킵니다. 제네릭 함수와 클래스를 활용하면 타입에 독립적인 코드를 작성할 수 있으며, 제약조건을 통해 필요한 범위 내에서 유연성을 유지할 수 있습니다. TypeScript의 제네릭은 코드를 보다 안전하고 효율적으로 작성할 수 있는 강력한 도구입니다.

'Language > TypeScript' 카테고리의 다른 글

TypeScript 타입 가드(Type Guards)  (0) 2023.10.17
Typescript 유니언(Union), 교차(Intersection) 타입  (0) 2023.10.16
TypeScript interface와 type aliasing  (0) 2023.10.16
TypeScript 함수 타입 정의  (0) 2023.10.16
TypeScript 객체(Object)와 배열(Array)에서의 타입  (0) 2023.10.16
Language/TypeScript 추천 글
more
  • TypeScript 타입 가드(Type Guards)
    TypeScript 타입 가드(Type Guards)2023.10.17
  • Typescript 유니언(Union), 교차(Intersection) 타입
    Typescript 유니언(Union), 교차(Intersection) 타입2023.10.16
  • TypeScript interface와 type aliasing
    TypeScript interface와 type aliasing2023.10.16
  • TypeScript 함수 타입 정의
    TypeScript 함수 타입 정의2023.10.16
FRONTMAN

검색

250x250

방문자 수

Total
Today
Yesterday

카테고리

  • 분류 전체보기 (54)
    • Language (48)
      • JavaScript (15)
      • TypeScript (14)
      • Python (14)
      • Dart (5)
      • Java (0)
    • FE (6)
      • WEB (4)
      • React (0)
      • Flutter (1)
    • CS (0)
      • Algorithm (0)
      • Network (0)
    • DevOps (0)

공지사항

  • 전체보기

최근 글

인기 글

태그

  • export
  • await
  • list
  • Import
  • async
  • 타입
  • OOP
  • npm
  • Flutter
  • 타입스크립트
  • 웹
  • Interface
  • js
  • 자바스크립트
  • JavaScript
  • Python
  • 파이썬
  • Object
  • tuple
  • Type
  • typeScript
  • function
  • CLASS
  • nodejs
  • frontend
  • web
  • inline frame
  • 리스트
  • DART
  • Modules

최근 댓글

FRONTMAN :: hahekaku
CopyrightBluemivDesigned byBluemiv

티스토리툴바