← Курс/Что такое TypeScript и зачем он нужен#140 из 257+20 XP

Что такое TypeScript и зачем он нужен

TypeScript = JavaScript + типы

TypeScript — это **надмножество JavaScript**, разработанное Microsoft. Любой валидный JS-код является валидным TS-кодом. TypeScript добавляет одну главную вещь: **статическую типизацию**.

// JavaScript — ошибку увидим только в runtime
function greet(name) {
  return 'Привет, ' + name.toUpperCase()
}

greet(42)  // TypeError в runtime: name.toUpperCase is not a function

// TypeScript — ошибку поймаем при компиляции
function greet(name: string): string {
  return 'Привет, ' + name.toUpperCase()
}

greet(42)  // Ошибка компиляции: Argument of type 'number' is not assignable to parameter of type 'string'

Зачем нужен TypeScript

**1. Поиск ошибок на этапе разработки** — TS проверяет типы до запуска кода. Опечатки в именах свойств, неправильные аргументы функций, несовместимые типы — всё это ловится до того, как код попадёт в продакшн.

**2. Поддержка IDE** — автодополнение, рефакторинг, навигация по коду работают значительно лучше. IDE «знает» что возвращает функция и какие поля есть у объекта.

**3. Самодокументирующий код** — типы являются частью документации. function save(user: User): Promise<void> — сразу понятно что принимает и возвращает функция.

**4. Безопасный рефакторинг** — при переименовании функции или изменении структуры объекта TS покажет все места, которые нужно обновить.

Как TypeScript компилируется в JavaScript

TypeScript **не запускается напрямую** в браузере или Node.js. Его нужно скомпилировать в JavaScript:

// Файл user.ts (TypeScript)
interface User {
  name: string
  age: number
}

function greetUser(user: User): string {
  return `Привет, ${user.name}!`
}

После компиляции tsc user.ts получаем user.js:

// Файл user.js (скомпилированный JavaScript)
function greetUser(user) {
  return `Привет, ${user.name}!`
}

Все аннотации типов **удаляются** при компиляции — в runtime их нет.

Инструменты

  • **tsc** — официальный компилятор TypeScript: npm install -g typescript, затем tsc файл.ts
  • **ts-node** — запуск .ts файлов напрямую без явной компиляции: npx ts-node файл.ts
  • **tsconfig.json** — конфигурация компилятора: строгость проверок, целевая версия JS, пути модулей
  • // Аннотации типов — синтаксис TypeScript
    const name: string = 'Алексей'
    const age: number = 30
    const isActive: boolean = true
    
    // TypeScript видит ошибки которые JS пропускает:
    let count: number = 0
    count = 'много'  // Ошибка TS: Type 'string' is not assignable to type 'number'

    TypeScript в продакшне

    TypeScript используется в Angular (официальный язык фреймворка), в большинстве React и Vue проектов, в NestJS, в крупных open-source проектах (VS Code написан на TS). По опросам Stack Overflow, TypeScript входит в топ самых любимых языков программирования несколько лет подряд.

    Примеры

    Runtime type checking — то, что TypeScript делает при компиляции, здесь делается вручную в JavaScript

    // TypeScript проверяет типы при компиляции.
    // В JavaScript нет компилятора, поэтому симулируем
    // проверку типов в runtime с помощью явных проверок.
    
    function strictAdd(a, b) {
      if (typeof a !== 'number') {
        throw new TypeError(`Аргумент a должен быть number, получен ${typeof a}`)
      }
      if (typeof b !== 'number') {
        throw new TypeError(`Аргумент b должен быть number, получен ${typeof b}`)
      }
      return a + b
    }
    
    // TypeScript аналог: function strictAdd(a: number, b: number): number
    
    function greetUser(user) {
      if (typeof user !== 'object' || user === null) {
        throw new TypeError(`Ожидается объект User, получен ${typeof user}`)
      }
      if (typeof user.name !== 'string') {
        throw new TypeError(`user.name должен быть string, получен ${typeof user.name}`)
      }
      return `Привет, ${user.name.toUpperCase()}!`
    }
    
    // TypeScript аналог:
    // interface User { name: string }
    // function greetUser(user: User): string
    
    function processItems(items) {
      if (!Array.isArray(items)) {
        throw new TypeError(`Ожидается массив, получен ${typeof items}`)
      }
      if (items.length > 0 && typeof items[0] !== 'string') {
        throw new TypeError('Ожидается массив строк')
      }
      return items.map(item => item.trim().toLowerCase())
    }
    
    // TypeScript аналог: function processItems(items: string[]): string[]
    
    // --- Демонстрация ---
    
    console.log('=== strictAdd ===')
    console.log(strictAdd(2, 3))      // 5
    console.log(strictAdd(10, -4))    // 6
    
    try {
      strictAdd('2', 3)               // TypeError — TS поймал бы это при компиляции
    } catch (e) {
      console.log(e.message)          // 'Аргумент a должен быть number, получен string'
    }
    
    console.log('\n=== greetUser ===')
    console.log(greetUser({ name: 'Алексей' }))  // 'Привет, АЛЕКСЕЙ!'
    
    try {
      greetUser({ name: 42 })         // TypeError — TS: Type 'number' is not assignable to type 'string'
    } catch (e) {
      console.log(e.message)          // 'user.name должен быть string, получен number'
    }
    
    console.log('\n=== processItems ===')
    console.log(processItems(['  Hello ', ' World']))  // ['hello', 'world']
    
    try {
      processItems('не массив')       // TypeError — TS: Argument of type 'string' is not assignable to parameter of type 'string[]'
    } catch (e) {
      console.log(e.message)
    }