Полное руководство по универсальным типам в TypeScript

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

  1. Основные универсальные функции.
    Универсальные функции позволяют определить функцию, которая может работать с различными типами параметров, сохраняя при этом безопасность типов. Вот пример:
function identity<T>(arg: T): T {
  return arg;
}
let result = identity<string>("Hello, World!");
console.log(result); // Output: Hello, World!
  1. Общие интерфейсы.
    Интерфейсы также можно сделать универсальными в TypeScript. Это позволяет создавать гибкие и повторно используемые интерфейсы, способные работать с разными типами. Вот пример:
interface Pair<T, U> {
  first: T;
  second: U;
}
let pair: Pair<number, string> = { first: 1, second: "two" };
console.log(pair); // Output: { first: 1, second: "two" }
  1. Ограничения типов.
    TypeScript позволяет накладывать ограничения на универсальные типы с помощью ключевого слова extends. Это гарантирует, что универсальный тип удовлетворяет конкретным условиям. Вот пример:
interface Comparable<T> {
  compareTo(other: T): number;
}
function max<T extends Comparable<T>>(a: T, b: T): T {
  return a.compareTo(b) > 0 ? a : b;
}
class Person implements Comparable<Person> {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  compareTo(other: Person): number {
    return this.name.localeCompare(other.name);
  }
}
let p1 = new Person("Alice");
let p2 = new Person("Bob");
let result = max(p1, p2);
console.log(result); // Output: { name: "Bob" }
  1. Псевдонимы типов с универсальными шаблонами.
    Псевдонимы типов позволяют создавать пользовательские типы многократного использования. Их можно комбинировать с дженериками для создания сложных определений типов. Вот пример:
type Pair<T, U> = [T, U];
let pair: Pair<number, string> = [1, "two"];
console.log(pair); // Output: [1, "two"]
  1. Утилиты типов:
    TypeScript предоставляет несколько встроенных утилит, которые можно использовать с универсальными типами для выполнения общих операций. Некоторые популярные из них включают Pick, Omit, Partial, Requiredи Record. Вот пример:
interface User {
  id: number;
  name: string;
  email: string;
}
type PartialUser = Partial<User>;
// Equivalent to:
// interface PartialUser {
//   id?: number;
//   name?: string;
//   email?: string;
// }
type RequiredUser = Required<User>;
// Equivalent to:
// interface RequiredUser {
//   id: number;
//   name: string;
//   email: string;
// }

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