Пошук уроків, статей та іншого контенту
Розберете життєвий цикл TypeScript-коду: перевірку типів, транспіляцію та виконання згенерованого JavaScript.
Браузер і Node.js виконують JavaScript. Вони не виконують TypeScript безпосередньо, тому файл TypeScript потрібно перетворити на JavaScript.
Типовий життєвий цикл має такий вигляд:
Розробник пише код у файлі .ts.
TypeScript перевіряє код і його типи.
Компілятор генерує JavaScript-файл .js.
Браузер або Node.js виконує згенерований JavaScript.
app.ts
↓
перевірка типів
↓
генерація JavaScript
↓
app.js
↓
виконання в браузері або Node.jsУ цьому процесі TypeScript-компілятор найчастіше запускають командою tsc.
Розглянемо простий файл app.ts:
const userName: string = "Олена";
const age: number = 25;
console.log(`${userName}, ${age} років`);TypeScript перевіряє, чи відповідають значення оголошеним типам:
const age: number = "25";Такий код містить помилку: рядок "25" не можна присвоїти змінній типу number.
Під час перевірки TypeScript повідомить про помилку ще до запуску програми. Це одна з головних переваг TypeScript: багато проблем можна знайти під час розробки, а не під час виконання.
Термін «транспіляція» означає перетворення коду з однієї мови або версії мови в іншу мову чи версію з подібним рівнем абстракції.
Під час транспіляції TypeScript:
видаляє типи;
перетворює сучасний синтаксис відповідно до налаштувань;
генерує JavaScript-файли.
Наприклад, файл app.ts:
function greet(name: string): string {
return `Привіт, ${name}!`;
}
const message = greet("Марія");
console.log(message);Після компіляції він може перетворитися на такий JavaScript:
function greet(name) {
return `Привіт, ${name}!`;
}
const message = greet("Марія");
console.log(message);Типи string зникли, оскільки JavaScript не використовує їх під час виконання.
TypeScript перевіряє типи під час розробки та компіляції, але типові анотації не потрапляють у згенерований JavaScript.
function add(a: number, b: number): number {
return a + b;
}Після транспіляції:
function add(a, b) {
return a + b;
}У JavaScript немає інформації про те, що a і b мали бути числами.
Тому TypeScript не може автоматично виправити неправильні дані, які надходять під час виконання:
function add(a: number, b: number): number {
return a + b;
}
const result = add("2" as unknown as number, 3);
console.log(result);Такий приклад штучно обходить перевірку типів. Під час виконання JavaScript може отримати непередбачуваний результат, оскільки типи TypeScript уже видалені.
Важливо розділяти:
перевірку типів — виконує TypeScript до запуску програми;
виконання коду — виконує JavaScript-рушій у браузері або Node.js.
Для роботи потрібні Node.js та менеджер пакетів, наприклад npm.
Створіть новий каталог і встановіть TypeScript як залежність для розробки:
mkdir typescript-demo
cd typescript-demo
npm init -y
npm install --save-dev typescriptПеревірити встановлену версію можна командою:
npx tsc --versionКоманда npx tsc запускає локальну версію TypeScript із поточного проєкту.
Створіть файл app.ts:
function greet(name: string): string {
return `Привіт, ${name}!`;
}
const message = greet("Ірина");
console.log(message);Запустіть компілятор:
npx tsc app.tsПісля цього поруч з’явиться файл app.js:
function greet(name) {
return `Привіт, ${name}!`;
}
const message = greet("Ірина");
console.log(message);Запустити JavaScript у Node.js можна так:
node app.jsРезультат:
Привіт, Ірина!Отже, Node.js запускає не app.ts, а згенерований app.js.
Налаштування TypeScript зберігають у файлі tsconfig.json. Його можна створити командою:
npx tsc --initМінімальний приклад конфігурації:
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"rootDir": "src",
"outDir": "dist",
"strict": true
},
"include": ["src"]
}Основні параметри:
target — версія JavaScript, яку потрібно генерувати;
module — формат модулів у згенерованому JavaScript;
rootDir — каталог із файлами TypeScript;
outDir — каталог для згенерованих JavaScript-файлів;
strict — суворіша перевірка типів;
include — файли або каталоги, які потрібно компілювати.
Створіть таку структуру:
typescript-demo/
├── src/
│ └── app.ts
├── package.json
└── tsconfig.jsonФайл src/app.ts:
function square(value: number): number {
return value * value;
}
const result = square(5);
console.log(result);Запустіть компілятор без зазначення конкретного файлу:
npx tscTypeScript прочитає tsconfig.json і створить:
dist/
└── app.jsЗапуск згенерованого файлу:
node dist/app.jsРезультат:
25Іноді потрібно лише перевірити типи, але не створювати JavaScript-файли. Для цього використовують параметр --noEmit:
npx tsc --noEmitУ такому режимі TypeScript:
прочитає файли проєкту;
перевірить типи;
покаже помилки;
не створить файли .js.
Це зручно для окремої перевірки коду або в автоматичних перевірках проєкту.
Якщо TypeScript знаходить помилку, він показує її в терміналі:
const count: number = "п'ять";Приклад повідомлення може мати такий вигляд:
Type 'string' is not assignable to type 'number'.Компілятор повідомляє, що значення типу string не можна використати там, де очікується number.
За замовчуванням TypeScript може згенерувати JavaScript навіть тоді, коли знайшов помилки типів. Щоб заборонити генерацію файлів із помилками, у tsconfig.json можна додати:
{
"compilerOptions": {
"noEmitOnError": true
}
}Тоді за наявності помилок перевірка завершиться невдало, а JavaScript не буде згенерований.
TypeScript може генерувати JavaScript для різних середовищ.
Наприклад:
{
"compilerOptions": {
"target": "ES5"
}
}У такому разі сучасний синтаксис може бути перетворений на старіший JavaScript, сумісніший зі старими середовищами.
Якщо середовище підтримує сучасний JavaScript, можна вибрати новішу цільову версію:
{
"compilerOptions": {
"target": "ES2020"
}
}target впливає на синтаксис згенерованого JavaScript, але не змінює логіку програми.
src/app.ts:
interface Product {
name: string;
price: number;
}
function formatProduct(product: Product): string {
return `${product.name}: ${product.price} грн`;
}
const product: Product = {
name: "Навушники",
price: 1200
};
console.log(formatProduct(product));npx tscПід час перевірки TypeScript переконається, що:
у product є властивості name і price;
name має тип string;
price має тип number;
функція повертає рядок.
dist/app.js може мати такий вигляд:
function formatProduct(product) {
return `${product.name}: ${product.price} грн`;
}
const product = {
name: "Навушники",
price: 1200
};
console.log(formatProduct(product));Інтерфейс Product повністю зник, тому що він потрібен лише для перевірки TypeScript-коду.
node dist/app.jsРезультат:
Навушники: 1200 грнПослідовність така:
tsc читає src/app.ts.
TypeScript перевіряє типи.
Інтерфейс і типові анотації видаляються.
JavaScript записується в dist/app.js.
Node.js виконує dist/app.js.
node src/app.tsNode.js зазвичай не може виконати TypeScript-файл із типами. Спочатку скомпілюйте його:
npx tsc
node dist/app.jsТипи TypeScript не є захистом від будь-яких неправильних даних під час виконання. Після компіляції вони видаляються.
const value: number = 10;У JavaScript залишиться лише:
const value = 10;Після компіляції потрібно запускати JavaScript із каталогу, указаного в outDir.
Якщо в конфігурації встановлено:
{
"compilerOptions": {
"outDir": "dist"
}
}запускати потрібно:
node dist/app.jsа не:
node src/app.tsПовідомлення TypeScript не слід просто пропускати. Помилка може означати, що програма містить неправильне припущення щодо даних або повертає не той тип.
Для перевірки без створення файлів використовуйте:
npx tsc --noEmitTypeScript-код зазвичай зберігається у файлах .ts.
Компілятор TypeScript перевіряє типи та генерує JavaScript.
Браузер і Node.js виконують згенерований JavaScript, а не типи TypeScript.
Типові анотації, інтерфейси та інші конструкції для перевірки типів зникають після компіляції.
npx tsc запускає компіляцію.
npx tsc --noEmit лише перевіряє код без генерації JavaScript.
tsconfig.json визначає, які файли компілювати та куди записувати результат.
Параметр target визначає цільову версію JavaScript.
Параметр outDir визначає каталог для згенерованих файлів.