Typescript — это полный язык (полный язык по Тьюрингу); таким образом, у него есть несколько ключевых слов для работы. Одним из таких ключевых слов является extends. Это ключевое слово может сбивать с толку, поскольку оно включает в себя несколько понятий или значений, которые зависят от контекста, в котором оно используется.

Наследство с extends

Наследование в Typescript позволяет вам создавать новые интерфейсы, которые наследуют или расширяют поведение предыдущего.

interface User {
  firstName: string;
  lastName: string;
  email: string;
}

interface StaffUser extends User {
  roles: Array<Role>
}

What you can see in the above snippet is:

  • The interface User describes a type with some properties that represent a user.
  • Интерфейс StaffUser представляет пользователя с теми же свойствами, что и User, но с еще одним: ролями.

Это использование расширений может использоваться для одновременного наследования от нескольких интерфейсов, просто используя имена базовых интерфейсов, разделенные запятыми.

interface StaffUser extends User, RoleUser {

}

Это поведение также можно использовать для расширения Class

расширяется как ограничение.

extends также можно использовать для ограничения типа или для сужения области действия типа.

export type QueryFunction<
  T = unknown,
  TQueryKey extends QueryKey = QueryKey,
> = (context: QueryFunctionContext<TQueryKey>) => T | Promise<T>

В приведенном выше примере (из реальной реализации tanstack-query) показан тип с именем QueryFunction. Это общий тип, который принимает два значения: T и TQueryKey.

Общее использование здесь очень похоже на функцию в javascript, которая принимает два аргумента.

Здесь важно отметить использование ключевого слова extends: TQueryKey extends QueryKey = QueryKey. Это может быть прочитано как TQueryKey и должно иметь тип Query со значением по умолчанию QueryKey.

Предыдущее использование расширений, сужающих или ограничивающих универсальный тип, является краеугольным камнем для возможности реализации условных типов, поскольку расширения будут использоваться в качестве условия для проверки того, не соответствует ли универсальный тип определенному типу.