← Назад к вопросам

Зачем нужны конструкции с помощью extends в TypeScript?

2.0 Middle🔥 171 комментариев
#TypeScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Зачем нужны конструкции extends в TypeScript

Конструкция extends в TypeScript — это один из самых мощных инструментов для работы с типами. Она используется в нескольких контекстах и позволяет создавать более гибкие, переиспользуемые и безопасные типы.

Использование в классах и интерфейсах

Первое и самое очевидное использование extends — наследование классов и расширение интерфейсов:

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

interface Dog extends Animal {
  breed: string;
}

const myDog: Dog = {
  name: "Rex",
  age: 5,
  breed: "Labrador"
};

Это позволяет переиспользовать уже определённые типы и избежать дублирования кода. Интерфейс Dog наследует все свойства Animal и добавляет свои собственные.

Условные типы (Conditional Types)

Одно из самых полезных применений extends — создание условных типов. Они работают как условные выражения, но для типов:

type IsString<T> = T extends string ? true : false;

type A = IsString<"hello">; // true
type B = IsString<123>; // false

Это особенно мощно при работе с generic-типами:

type Flatten<T> = T extends Array<infer U> ? U : T;

type Str = Flatten<string[]>; // string
type Num = Flatten<number>; // number

Здесь infer извлекает тип элемента из массива. Если T — это массив, мы возвращаем тип элемента, иначе возвращаем сам T.

Ограничение generic-параметров (Constraints)

extends используется для ограничения того, какие типы могут быть переданы в generic-функцию или интерфейс:

function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const person = { name: "John", age: 30 };
const name = getProperty(person, "name"); // OK
getProperty(person, "email"); // Ошибка: "email" не существует в person

Здесь T extends object гарантирует, что T — это объект, а K extends keyof T гарантирует, что K — это один из ключей объекта T.

Распределение условных типов (Distributive Conditional Types)

Когда условный тип применяется к union-типу, он распределяется по каждому элементу union:

type ToArray<T> = T extends any ? T[] : never;

type A = ToArray<string | number>; // string[] | number[]

Это мощный инструмент, но может привести к неожиданному поведению, если не понимать, как это работает.

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

Популярный пример — функция, которая работает с объектами и их значениями:

type ExtractProperty<T, K extends keyof T> = T[K];

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

type UserId = ExtractProperty<User, "id">; // number
type UserName = ExtractProperty<User, "name">; // string

Почему это важно

extends позволяет:

  • Создавать более точные типы, которые предотвращают ошибки на этапе разработки
  • Писать переиспользуемые компоненты и функции, которые работают с разными типами
  • Избежать типа any, что критично для больших проектов
  • Автоматизировать преобразование типов через утилиты

Без extends TypeScript был бы намного менее мощным инструментом для работы с типами. Это основа для создания сложных type utilities, которые используются в React, Next.js и других популярных библиотеках.

Зачем нужны конструкции с помощью extends в TypeScript? | PrepBro