Ключевое слово 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
по-прежнему проходит, даже несмотря на то, что в нем есть возраст в качестве дополнительного параметра. свойство.