JavaScript має невеликий набір рантайм-типів і перевіряє їх під час виконання.
TypeScript — це надмножина JS із статичною системою типів, яка перевіряє форми даних до запуску (на етапі компіляції). Типи TS існують лише під час білду й зникають у згенерованому JS.
1) Типи в JavaScript (runtime)
Примітиви:
string
,number
(усі числа — 64-біт float),boolean
null
,undefined
bigint
,symbol
Складний:
object
(у т.ч. масиви, функції, дати тощо)
Особливості:
- Динамічна типізація: змінна може міняти тип.
- Дрібні «граблі»:
typeof null === 'object'
,NaN
— число, автоприведення. - Є обгортки (
String
,Number
,Boolean
) — це об’єкти, не плутати з примітивами.
2) Типи в TypeScript (compile-time)
Є відповідники JS-типів плюс інструменти, яких у JS немає:
- Базові:
string
,number
,boolean
,bigint
,symbol
,null
,undefined
,object
- Спеціальні:
any
,unknown
,never
,void
- Union/Intersection:
A | B
,A & B
- Літеральні типи:
'ok' | 'error'
,42
- Кортежі (tuple):
[number, string]
- Шаблонні літеральні типи:
`id_${number}`
- Generics:
Array<T>
,Promise<T>
, свої узагальнення - Інтерфейси та type-аліаси:
interface User {…}
,type User = {…}
- Utility types:
Partial<T>
,Pick<T, K>
,Exclude<A, B>
тощо - Enum (звичайні еnum компілюються в JS-код;
const enum
— прибираються на етапі трансляції)
TS — структурно типізований: сумісність визначається формою об’єкта, а не ім’ям типу.
3) Що принципово відрізняється
- Місце перевірки:
JS ловить помилки типів тільки в рантаймі; TS попереджає про них на етапі збірки. - Наявність типів, яких немає в JS:
unknown
,never
, кортежі, об’єднання/перетини — це суто TS-концепти. - Null-безпека: у режимі
strictNullChecks
значенняnull/undefined
не сумісні з іншими типами без явної обробки. - Примітив vs обгортка: у TS чітко розрізняють
string
(примітив) іString
(об’єктний тип, краще не використовувати). - Type erasure: після компіляції усі TS-типи зникають, залишається чистий JS.
4) Короткі приклади
JS (може впасти лише під час виконання):
function greet(user) {
return 'Hi, ' + user.name.toUpperCase(); // впаде, якщо user або name не тієї форми
}
TS (ловить на етапі компіляції):
type User = { name: string };
function greet(user: User) {
return 'Hi, ' + user.name.toUpperCase();
}
greet({ name: 'Ann' }); // ок
greet({}); // ❌ помилка типу ще до запуску
Union + звуження:
function len(x: string | string[]) {
return typeof x === 'string' ? x.length : x.length; // ок: TS розуміє обидва випадки
}
Кортеж:
const pair: [number, string] = [1, 'a']; // фіксована кількість і порядок
unknown
vs any
:
let a: any = getSomething(); // можна робити що завгодно (менше безпеки)
let u: unknown = getSomething(); // треба звузити перед використанням
if (typeof u === 'string') console.log(u.toUpperCase());
5) Зручна «шпаргалка» відповідностей
JS (рантайм) | TS (compile-time) | Коментар |
---|---|---|
string | string , літеральні 'a' | 'b' | У TS є точні літерали |
number | number | Ті ж самі числа, але тип перевіряється статично |
boolean | boolean | — |
null /undefined | null , undefined | У strictNullChecks не змішуються з іншими |
object | object , Record<K,V> , інтерфейси | Структурна сумісність |
масив | T[] , Array<T> | — |
функція | (args) => ret | Сигнатури функцій типізуються |
— | any , unknown , never , void | Лише в TS |
— | union , intersection , tuple , enum | Лише в TS |