Ты неправильно используешь интерфейсы typescript
- вторник, 23 апреля 2024 г. в 00:00:05
A: Не думай о помощи.
Б: Сложно не думать о помощи, когда пишешь на javascript.
Примерно такой диалог я слышал на одной из конференции. Решить проблему отсутствия строгой типизации был призван typescript.
Конкретно в этой статье я хотел бы рассмотреть один из приемов использования интерфейсов typescript, который мне кажется неочевидным, его я подсмотрел и смог оценить его преимущества в процессе написания приложений на языке golang.
Для большинства typescript разработчиков типы и интерфейсы, не имеют как таковой большой разницы.
type Dog = {name: string, age: number}
interface Dog {
name: string,
age: number
}
И запись при помощи интерфейса и при помощи типа по своей сути равнозначно смогут дальше работать, и подсказывать ошибки типизации при дальнейшей разработке
Я предлагаю разделять эти 2 понятия:
Типы используем когда хотим описать определенные атрибуты объектов.
Интерфейсы когда хотим описать поведение объектов, их методы.
Для начала создадим интерфейс “greeter”.
interface greeter {
greet() : void;
}
Создадим типы “Dog” и “Cat”.
type Dog = {name: string, age: number}
type Cat = {first_name: string, second_name: string, owner: string}
Как мы видим эти типы, имеют различные наборы атрибутов.
Далее создадим функцию, которая принимает в качестве первого аргумента, объект удовлетворяющий интерфейсу “greeter” и далее вызывает его метод “greet”.
function greet(g: greeter) {
g.greet();
}
Что-бы наши типы “Dog” и “Cat”, можно было использовать при вызове функции “greet”, необходимо явно объединить типы “Dog” и “Cat” c интерфейсом “greeter”
type Dog = {name: string, age: number} & greeter
type Cat = {first_name: string, second_name: string, owner: string} & greeter
Реализуем объект каждого типа
const dog: Dog = {
name: "jack",
age: 10,
greet() {
console.log(`hello im dog. My name is ${this.name}. I'm ${this.age} years old.`)
}
}
const cat: Cat = {
first_name: "Myley",
second_name: "Meows",
owner: "Ivan",
greet() {
console.log(`hello im cat. My name is ${this.first_name} ${this.second_name}. My owner name is ${this.owner}`);
}
}
Что мы имеем? У нас 2 объекта, разные по своей реализации, но их объединяет наличие метода, указанного в интерфейсе “greeter”
Вызовем эти методы
greet(dog);//"hello im dog. My name is jack. I'm 10 years old."
greet(cat);//"hello im cat. My name is Myley Meows. My owner name is Ivan"
Интерфейсы позволяют разделять реализацию от так называемого слоя бизнеса.
Например с точки зрения реализации пользователя и администратора в рамках одного приложения, они могут иметь различный набор атрибутов. Но в конце концов для их создания, нужно использовать один и тот же хендлер бекенда.
Код становится чище и в результате более легким для восприятия.
Позволяет разделять приложения, на более мелкие, независимые слои.