Менше типів — більше чистоти: TypeScript, який вам сподобається

💡 Усі статті, обговорення, новини про Front-end — в одному місці. Приєднуйтесь до Front-end спільноти!

Як кодувати на TypeScript, поважаючи DRY/KISS?

TypeScript — потужна мова, яка допомагає зробити код безпечнішим. Але багато розробників додають зайві декларації, навіть коли TypeScript сам вже все знає. Це не лише робить код важким для читання, а й ускладнює його підтримку. Давайте розглянемо, як застосовувати TypeScript ефективно, не перевантажуючи код зайвими деклараціями.

Довіряйте Type Inference

TypeScript чудово визначає типи автоматично. Тому не потрібно їх декларувати явно, якщо це можна вивести зі значення.

🤨 Раніше писав:

const age: number = 25;

👍 Зараз так:

const age = 25; // TypeScript сам виведе тип як `number`

Не декларуйте тип результату функції

TypeScript автоматично виводить тип повернення функції.

🤨 Раніше писав:

const add = (a: number, b: number): number => {
  return a + b;
};

👍 Зараз так:

const add = (a: number, b: number) => a + b; // TypeScript виведе `number`

Варто вказувати явний тип, якщо:

  • функція складна або має кілька return,
  • повертається void або Promise<void>,
  • це частина публічного API,
  • використовується Generic<T>.

Тобто правило просте: якщо тип очевидний — не дублюємо, якщо неочевидний — явно вказуємо.

Мінімум типів при деструктуризації

🤨 Раніше писав:

const user: { name: string; age: number } = { name: "Alice", age: 25 };
const { name, age }: { name: string; age: number } = user;

👍 Зараз так:

const user = { name: "Alice", age: 25 };
const { name, age } = user; // TypeScript сам знає, що це `string` і `number`

(React) не визначайте тип useState, якщо це очевидно

🤨 Раніше писав:

const [count, setCount] = useState<number>(0);

👍 Зараз так:

const [count, setCount] = useState(0); // TypeScript сам визначить `number`

✅ Висновок

Так ваш код буде чистішим та легшим у підтримці і не перевантаженим зайвими деклараціями. 🚀

👍ПодобаєтьсяСподобалось1
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Тут би ще про is, assert та дженерики. За їх правильного використання життя стає сильно краще

const add = (a: number, b: number) => a + b; // TypeScript виведе `number`

Чудовий приклад, але він обламується об Призму, коли вам треба оперувати складними об’єктами. Наприклад у вас є Юзер, що має багато Документів, що мають багато Відміток. А тепер вам треба зробити хелпери для побудови дерева об’єктів для вставки та зміни (тут інша структура буде, без полей ключів). Без ексорту типів ви будете витрачати багато часу на розбір помилок «поле не існує», при змінах структури об’єктів.

Використовуйте typeof та ReturnType замість дублювання типів

Може бути корисно в деяких випадках. Наприклад, якщо використовуєте зод.
В загальному випадку, те що ви сказали перекладається як «забийте на дизайн фазу розробки». На ваших тривіальних прикладах це ок, в середньому проекті, може виявитись, що createUser повертає не Корастувача, а якогось КористувачаЗКупоюДодатковихПолів і ви сідаєте посеред проекту та замість додавання функціональності починаєте з’ясовувати чи комусь потрібне оте поле, яке ви не знаєте як заповнити (наприклад age)

Раніше писав:

const age: number = 25;

А для чого ви так писали? Якось складно зрозуміти для чого тип для констант.
От для змінних в тестах воно потрібно. І це є прикладом також до попередніх зауважень — вам треба змінна, яка ініціалізується в бефорЕач, а типу у вас немає, бо це об’єкт, що «визначається як частина дерева іншого об’єкта».

Дякую за ґрунтовний коментар! Ви підняли важливі аспекти, особливо щодо ReturnType + typeof, складних структур даних та динамічних змін об’єктів.

Щодо простих прикладів (add, age)

Вони наведені саме для ілюстрації базових принципів type inference. Очевидно, що в реальних проєктах ситуація складніша, і там іноді доводиться експортувати типи явно, особливо при роботі з глибоко вкладеними структурами. Але суть статті в тому, щоб не дублювати зайві декларації, коли TypeScript уже справляється сам.

Щодо складних об’єктів

Ви абсолютно праві: у випадку вкладених структур, особливо коли вони змінюються, корисно явно визначати типи. Я згоден, що в масштабних проєктах без цього може бути важко.

Щодо тестів

Так, у тестах і підготовчих блоках (наприклад, beforeEach) явне визначення типів може бути необхідним, особливо якщо працюєте з об’єктами, що змінюються під час тестування. Це хороший кейс.

Підписатись на коментарі