Вивчай

Вступ до TypeScript

Вступ до TypeScript — точність типів як архітектурне кресленняВступ до TypeScript — точність типів як архітектурне креслення

У Block 6 ми написали чимало JavaScript-коду: класи, async/await, модулі. JavaScript -- потужна мова, але у неї є одна суттєва проблема: помилки часто виявляються тільки під час виконання. TypeScript вирішує цю проблему, додаючи систему типів, яка перевіряє код ще до запуску.


Навіщо потрібен TypeScript?

Уяви таку ситуацію в JavaScript:

function greet(user) {
  return `Привіт, ${user.name}!`;
}

greet("Олексій"); // Привіт, undefined!

Функція очікує об'єкт з полем name, але ми передали рядок. JavaScript не скаже про помилку -- просто поверне "Привіт, undefined!".

Подивись, як TypeScript ловить таку помилку ще до запуску:

TypeScript знаходить помилку типів під час компіляціїTypeScript знаходить помилку типів під час компіляції

А тепер те саме в TypeScript:

function greet(user: { name: string }) {
  return `Привіт, ${user.name}!`;
}

greet("Олексій"); // Помилка компіляції!
// Argument of type 'string' is not assignable to parameter of type '{ name: string }'

TypeScript знаходить помилку до запуску програми, прямо в редакторі коду.

Що таке TypeScript?

  • TypeScript (TS) -- це надмножина JavaScript (superset): будь-який JS-код є валідним TS-кодом
  • TypeScript додає статичну типізацію -- перевірку типів на етапі компіляції
  • TS компілюється в звичайний JavaScript, який виконується в браузері або Node.js
  • TypeScript створений Microsoft і використовується в Angular, React, Next.js, Vue та багатьох інших проєктах
Інфо

TypeScript не працює напряму в браузері. Код .ts потрібно скомпілювати в .js. Цей процес називають транспіляція (transpilation).


Встановлення та перший проєкт

Встановлення TypeScript

Ось як виглядає весь процес — від створення проєкту до запуску скомпільованого JS:

TypeScript: створення проєкту, компіляція та запускTypeScript: створення проєкту, компіляція та запуск

# Створюємо папку проєкту
mkdir ts-intro && cd ts-intro

# Ініціалізуємо package.json
npm init -y

# Встановлюємо TypeScript як dev-залежність
npm install -D typescript

Файл tsconfig.json

Це конфігурація TypeScript-компілятора. Створюємо його командою:

npx tsc --init

Файл буде містити багато опцій з коментарями. Ось ключові:

{
  "compilerOptions": {
    "target": "ES2020",        // у який JS компілювати
    "module": "ESNext",        // система модулів
    "strict": true,            // суворий режим перевірки типів
    "outDir": "./dist",        // куди складати скомпільовані .js файли
    "rootDir": "./src",        // де шукати .ts файли
    "esModuleInterop": true,   // сумісність з ES-модулями
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}
Увага

Завжди вмикай "strict": true -- це найкращий спосіб отримати максимум від TypeScript. Він увімкне перевірку на null, undefined, неявний any та багато іншого.

Перший TypeScript-файл

Створи src/index.ts:

const message: string = "Привіт, TypeScript!";
console.log(message);

Скомпілюй та запусти:

# Компіляція
npx tsc

# Запуск скомпільованого JS
node dist/index.js

Додай npm scripts у package.json:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsc --watch"
  }
}

tsc --watch автоматично перекомпілює файли при збереженні.


Базові типи

TypeScript має ті ж типи, що й JavaScript, плюс кілька додаткових:

Примітивні типи

// string
const name: string = "Олексій";
const greeting: string = `Привіт, ${name}!`;

// number (цілі та дробові)
const age: number = 25;
const price: number = 99.99;
const hex: number = 0xff;

// boolean
const isActive: boolean = true;
const hasAccess: boolean = false;

null та undefined

const empty: null = null;
const notDefined: undefined = undefined;
Інфо

У строгому режимі (strict: true) не можна присвоїти null або undefined іншим типам: const name: string = null -- помилка! Це дуже корисно, бо саме null/undefined -- найчастіша причина багів.


Type annotations -- анотації типів

Type annotation -- це спосіб явно вказати тип змінної, параметра або return-значення:

// Анотація для змінної
let count: number = 0;
count = 10;     // OK
// count = "десять"; // Помилка: Type 'string' is not assignable to type 'number'

// TypeScript може визначити тип автоматично (type inference)
let city = "Київ"; // TypeScript знає, що це string
// city = 42;       // Помилка!

Type inference -- автовиведення типів

TypeScript часто може визначити тип сам, без явної анотації:

// Тип визначається автоматично
let score = 100;          // number
let title = "TypeScript"; // string
let isReady = true;       // boolean
const items = [1, 2, 3];  // number[]

// Не потрібно писати зайві анотації
let count: number = 0; // зайве -- TS і так зрозуміє
let count = 0;          // краще -- TS визначить тип сам
Порада

Правило: додавай анотації типів тільки там, де TypeScript не може визначити тип сам, або там, де явний тип покращує читабельність. Для параметрів функцій анотації зазвичай обов'язкові.


Типізація функцій

Для функцій вказуємо типи параметрів і значення, що повертається:

// Параметри та return type
function add(a: number, b: number): number {
  return a + b;
}

console.log(add(2, 3));      // 5
// console.log(add("2", "3")); // Помилка!

// Arrow function
const multiply = (a: number, b: number): number => a * b;

// Функція без return (void)
function logMessage(message: string): void {
  console.log(message);
}

Optional та default параметри

// Optional параметр (може бути undefined)
function greet(name: string, greeting?: string): string {
  return `${greeting || "Привіт"}, ${name}!`;
}

greet("Олексій");           // "Привіт, Олексій!"
greet("Олексій", "Вітаю"); // "Вітаю, Олексій!"

// Default параметр
function createUser(name: string, role: string = "user"): string {
  return `${name} (${role})`;
}

createUser("Марія");          // "Марія (user)"
createUser("Марія", "admin"); // "Марія (admin)"

Масиви

Є два способи типізувати масиви:

// Спосіб 1: тип[]
const numbers: number[] = [1, 2, 3, 4, 5];
const names: string[] = ["Олексій", "Марія", "Іван"];
const flags: boolean[] = [true, false, true];

// Спосіб 2: Array<тип> (generic syntax)
const scores: Array<number> = [100, 95, 87];
const words: Array<string> = ["hello", "world"];

// TypeScript контролює елементи масиву
numbers.push(6);     // OK
// numbers.push("7"); // Помилка: Argument of type 'string'...

// Масив об'єктів
const users: { name: string; age: number }[] = [
  { name: "Олексій", age: 25 },
  { name: "Марія", age: 30 },
];

Компіляція -- як це працює

TypeScript-файл (.ts) перетворюється в JavaScript (.js):

// src/math.ts (TypeScript)
function square(n: number): number {
  return n * n;
}

const result: number = square(5);
console.log(result);

Після npx tsc:

// dist/math.js (JavaScript)
"use strict";
function square(n) {
  return n * n;
}
const result = square(5);
console.log(result);

Зверни увагу: всі анотації типів зникли. TypeScript перевіряє типи під час компіляції, а потім видаляє їх. Браузер або Node.js отримує звичайний JavaScript.

Інфо

Помилки типів не блокують компіляцію за замовчуванням -- tsc все одно створить .js файли. Щоб заблокувати, додай "noEmitOnError": true до tsconfig.json.


VS Code та TypeScript

VS Code має вбудовану підтримку TypeScript. Ти отримуєш:

  • Автодоповнення -- VS Code підказує доступні властивості та методи
  • Перевірка помилок -- червоне підкреслення прямо в редакторі
  • Hover-інформація -- наведи курсор на змінну, щоб побачити її тип
  • Перехід до визначення -- Ctrl+Click на функцію, щоб перейти до її коду

Це одна з головних причин популярності TypeScript -- Developer Experience (DX) значно кращий, ніж у чистому JavaScript.


Підсумок

  • TypeScript -- надмножина JavaScript з системою типів
  • Типи перевіряються на етапі компіляції, а не виконання
  • Базові типи: string, number, boolean, null, undefined
  • Type annotations -- явне вказання типу через : тип
  • Type inference -- TypeScript може визначити тип автоматично
  • Масиви типізуються як тип[] або Array<тип>
  • tsconfig.json -- конфігурація компілятора; завжди вмикай strict: true
  • TypeScript компілюється в звичайний JavaScript командою tsc

Що далі?

У наступному уроці ми поглибимо знання типів: дізнаємось про union types, literal types, type aliases та різницю між any, unknown і never. Це дасть змогу описувати складніші структури даних.

Інфо

Корисні посилання:

Відео:

Більше корисних YouTube-каналів та інструментів — на сторінці ресурсів.