Інтерефейси в TS це тіж самі типи, але створення для обʼєктів. Коли ви створюєете обʼєкт, ви повинні створити також інтерфейс, в якому будуть зазначені всі типи для всіх ключів.
Базовий приклад:
interface User {
name: string;
age: number;
isActive: boolean;
}
const user: User = {
name: "Олександр",
age: 30,
isActive: true,
};
console.log(user.name); // Олександр
Також в інтерфейсах є один нюанс, вам потрібно зазнчати всі значення, які використовуються, та ви не можете залишити їх пустими. Тобто, якщо в інтерфейсі ви вказали age, то поле age обовʼязково повинно бути в обʼєкті. І навпаки, якщо ви щось не вказали в інтерфейсі, то його не може бути в обʼєкті. Для вирішення цієї проблеми є спеціальний оператор - ?
.
interface User {
name: string;
glory: string | number | null,
age?: number; // Може бути відсутнім
}
const user: User = {
name: "Анна",
glory: 25
};
console.log(user.age); // undefined
Readonly
Я вважаю що це перша користна властивість. Звістно, в звичайному JS ви також можете використовувати object prototype freeze, або аналоги, але тут це робиться однією строчкою. Ви можете визначати ключі, які не можна буде змінювати.
interface User {
readonly id: number;
name: string;
}
const user: User = {
id: 1,
name: "Олексій",
};
// user.id = 2; // Помилка: властивість лише для читання
console.log(user.id); // 1
Функції в інтерфейсах
Щодо функцій в інтерфейсах, то ва також треба буде зазначати в них параметри, а також те, що вони повертають. Це можна зробити ось так:
interface Calculator {
add(a: number, b: number): number;
subtract(a: number, b: number): number;
}
const calculator: Calculator = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
};
console.log(calculator.add(5, 3)); // 8
В принципі, як я казав уже раніше, весь тайпскрипт, це про додавання типізації до будь чого. Тобто перетворення динамічного JS, в статичний С мабуть.
Індексовані типи
Індексовані типи, це коли у вас в обʼєкті може бути багато невизначених типів, але всі вони повинні належати до якогось типу. Це можна реалізувати ось так:
interface UserDictionary {
[key: string]: string; // Індексовані значення
admin: number; // Конкретна властивість
}
const users: UserDictionary = {
admin: 35,
editor: "Анна",
guest: "Іван",
};
console.log(users.admin); // 35
console.log(users.editor); // Анна
Динамічні ключі
Це коли вам потрібно створити тип, динамічний тип, чи данмічне значення, тоді можна використати Record, в якому ви можете перерахувати ключі, та динамічні значення приклад:
type RoleDictionary = Record<"admin" | "editor" | "guest", string | number>;
const roles: RoleDictionary = {
admin: "Адміністратор",
editor: "Редактор",
guest: "Гість",
};
console.log(roles.admin); // Адміністратор
Іморт інтерфейсів
Думаю це одне з самих головних рішень. Трохи пізніше ми розберемо, як налаштовувати автоімпорт інтерфейсів, але зараз я покажу я просто зробити імпорт. Інтерфейси по факту можна экспортувати як звичайні змінні:
// interfaces.ts
export interface User {
id: number;
name: string;
email: string;
}
export interface Product {
id: number;
title: string;
price: number;
}
// index.ts
import { User, Product } from './interfaces';
const user: User = {
id: 1,
name: "Олексій",
email: "oleksii@example.com",
};
const product: Product = {
id: 101,
title: "Ноутбук",
price: 25000,
};
І коли ми дошли до імпорта, мабуть постало логічне питання, а як розширювати інтерфейси, якщо для якогось конкретного модуля, це стало необхідним:
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
position: string;
}
const employee: Employee = {
name: "Марія",
age: 28,
position: "Менеджер",
};
console.log(employee.position); // Менеджер
Тут все дуже просто, ви можете прописати, або імпортувати будь який інтерфейс, і після розиширити його, за домогою extends в новий інтерфейс, наприклад Employee.
І це також чудово працює з імпортами:
import { User } from './interfaces.ts';
interface Employee extends User {
position: string;
}
const user: Employee = {
id: 1,
name: "Олексій",
email: "oleksii@example.com",
position: "adwawd"
};
На цьому мабуть все, побачимося в наступному уроці