Ключевое слово Typescript extends очень мощное и полезное, оно позволяет избежать ненужного дублирования свойств типа, а также помогает определить специфичность типов. Вот 2 известных случая использования ключевого слова extends.

Наследование

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

interface Animal {
	name: string,
	weight: number,
}
interface Honeybadger {
	name: string,
	weight: number,
	skin: string, 
	color: string,
}
/** 
	we can avoid duplication on the HoneyBadger by using the
 typescript extends keyword
*/
interface Honeybadger extends Animal {
	skin: string, 
	color: string,
}
/** 
	Honeybadger inherits name and weight attributes from Animal, but also has 
	the skin and color property as well
*/

Общие ограничения

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

Например, мы можем создать функцию универсального типа, которая получает параметр T и повторно использовать этот тип в разных контекстах.

type Log<T> = (content: T) => void
// Log T = string
const consoleString: Log<string> = (content) => console.log(content)
// Log T = {error: string}
const consoleError: Log<{error: string}> = (content) => console.error(content)

Однако иногда мы хотим ограничить или ограничить универсальный тип, который можно использовать или передать, и extends сияет в этом отношении. Например

type Log<T extends {name: string}> = (content: T) => void
/** ❌ throws error 
	Type 'string' does not satisfy the constraint '{ name: string; }'
*/
const consoleString: Log<string> = (content) => console.log(content)
type User = {
	name: string
}
type Animal = {
	name: string;
	age: number;
}
// ✅ passes
const consoleName: Log<User | Animal> = (content) => console.log(content.name)

В приведенных выше фрагментах кода тип Log принимает универсальный тип T , но есть условие для T, условие, использующее ключевое слово extends, которое указывает, что T должно иметь по крайней мере свойство name типа string , поэтому T не может быть типа string или любого другого типа, для которого не указано свойство.

Важно отметить, что ограничение для типа не обязательно должно быть точным, например, тип Animal по-прежнему проходит, даже несмотря на то, что в нем есть возраст в качестве дополнительного параметра. свойство.