Все статьи

TypeScript Generics: Практическое Руководство для Разработчиков Бэкенда

·MAGMA

TypeScript предлагает широкий спектр инструментов для создания типобезопасного и эффективного кода. Одним из наиболее мощных инструментов в этом арсенале являются generics, которые позволяют писать многократно используемый код без дублирования функций или использования неопределенных типов.

Основные Концепции

Чтобы начать работу с generics, необходимо понять их основную идею. Generics позволяют функциям и классам работать с различными типами данных, не теряя типобезопасности. Например, функция, которая возвращает первый элемент массива, может быть определена с использованием generics:

function getFirst<T>(items: T[]): T | undefined {
  return items[0];
}

Это определение гарантирует, что функция getFirst может быть использована с массивами любого типа, но при этом обеспечивает типобезопасность, поскольку TypeScript может определить тип возвращаемого значения на основе типа массива.

Generic API Ответы

Generics особенно полезны при работе с API, где ответы могут иметь различные структуры и типы данных. Например, можно определить интерфейс ApiResponse, который использует generics для описания типа данных в ответе:

interface ApiResponse<T> {
  data: T;
  meta: {
    page: number;
    total: number;
  };
}

Этот интерфейс можно использовать для определения функций, которые выполняют запросы к API и возвращают ответы с типобезопасными данными:

async function fetchPaginated<T>(url: string): Promise<ApiResponse<T>> {
  return (await fetch(url)).json();
}

Generic Репозиторий

Generics также могут быть использованы для создания классов, которые работают с различными типами данных. Например, можно определить класс Repository, который использует generics для описания типа данных, с которым он работает:

class Repository<T extends HasId> {
  constructor(private collection: string) {}

  async findById(id: string): Promise<T | null> {
    return db.collection(this.collection).findOne({ id });
  }

  async create(data: Omit<T, "id">): Promise<T> {
    const doc = { ...data, id: randomUUID() } as T;
    await db.collection(this.collection).insertOne(doc);
    return doc;
  }
}

Этот класс можно использовать для создания репозиториев, которые работают с различными типами данных, обеспечивая при этом типобезопасность и многократное использование кода.

Утилитные Типы

TypeScript предлагает ряд утилитных типов, которые могут быть использованы в сочетании с generics для создания ещё более мощных и гибких инструментов. Например, можно использовать типы Partial, Pick, Omit и Record для манипуляции типами данных и создания новых типов на основе существующих. Эти типы могут быть особенно полезны при работе с generics и создании типобезопасных и эффективных решений для задач бэкенда.

Вернуться к блогу