Різниця типів даних Javascript, Typescript

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)Коментар
stringstring, літеральні 'a' | 'b'У TS є точні літерали
numbernumberТі ж самі числа, але тип перевіряється статично
booleanboolean
null/undefinednull, undefinedУ strictNullChecks не змішуються з іншими
objectobject, Record<K,V>, інтерфейсиСтруктурна сумісність
масивT[], Array<T>
функція(args) => retСигнатури функцій типізуються
any, unknown, never, voidЛише в TS
union, intersection, tuple, enumЛише в TS