Перейти к основному содержимому

Синтаксис и пунктуация TypeScript

Разработчику

Дальше: Типы и типизация · Функции · Объекты и классы · Справочник — интерфейсы


TypeScript — это JavaScript плюс система типов. Синтаксис выполнения (скобки, запятые, function) совпадает с JS; сверху идут аннотации : T, interface, type, дженерики <T>. В статье — базовая грамматика TS и выбор между interface и type; полные таблицы — в 301.

Маршрут: Первая программасинтаксисТипы и типизацияфункции.

База JS: синтаксис JavaScript. Таблицы конструкций — Справочник — интерфейсы.


Что добавляет TypeScript к JavaScript

type User = {
id: string;
name: string;
};

function printUser(user: User): void {
console.log(user.name);
}
ЭлементПримерГде в рантайме
Аннотация параметраuser: Userисчезает
Возврат функции: voidисчезает
type / interfaceUserисчезает
import typeтолько типыисчезает

В .js после tsc остаётся обычный JavaScript — 15.md.


Пунктуация: JS + типы

СимволВ JSВ TS дополнительно
:метки в объектах { a: 1 }аннотация name: string
|union A | B
&intersection A & B
<>дженерики Array<T>, JSX в .tsx
?optional chaining ?.optional property email?
!логическое НЕnon-null assertion x! (осторожно)
...spread/restто же + в типах rest tuple
;часто опционаленто же

Точка с запятой между полями interface зависит от стиля команды; ASI из JS сохраняется. Знак ? после имени поля означает, что свойство может отсутствовать: email?: string эквивалентно email: string | undefined.


Объявление типов: type

type Id = string;
type Status = "idle" | "loading" | "done";
type Point = { x: number; y: number };
type Handler = (event: MouseEvent) => void;

Ключевое слово type задаёт алиас, то есть новое имя для типа. Union литералов вроде Status — основа discriminated unions; подробнее в 12.md.


Объявление контрактов: interface

interface Person {
readonly id: string;
name: string;
email?: string;
}

interface Employee extends Person {
department: string;
}

Разбор:

  • extends у интерфейсов — объединение полей.
  • interface можно дополнять (declaration merging) — полезно для .d.ts библиотек, редко в прикладном коде.

Полный список возможностей интерфейса (индексные сигнатуры, callable) — Справочник — интерфейсы.


interface vs type: когда что

ЗадачаПредпочтение
Форма объекта, публичный APIinterface
Union, tuple, mapped typestype
Расширение объектаinterface extends или type + &
Примитивный алиас type Id = stringтолько type
interface Animal {
name: string;
}

type Pet = Animal & {
ownerId: string;
};

type Result = { ok: true; data: string } | { ok: false; error: string };

Разбор:

  • Для React props и DTO часто interface; для результата операцииtype с union.
  • В 18.md класс может implements interface.
Правило команды

Важнее единообразие в команде, чем бесконечный спор interface vs type. Зафиксируйте стиль в ESLint / code review — рекомендации.


Пересечение типов (&)

type Timestamps = {
createdAt: Date;
updatedAt: Date;
};

type User = {
id: string;
name: string;
} & Timestamps;

Разбор:

  • & объединяет все поля; конфликтующие несовместимые свойства дадут never.
  • Для объектов часто читаемее один interface с extends.

Импорт только типов: import type

import type { User } from "./models.js";
import { createUser, type UserDto } from "./api.js";

export type { User };

Разбор:

  • import type гарантирует: импорт удалится при компиляции — нет лишних зависимостей в JS.
  • Смешанный импорт value + type — TypeScript 4.5+.
  • В runtime-модулях путь часто с .js при NodeNext9.md.

Экспорт типов

// types.ts
export interface Config {
port: number;
}

export type LogLevel = "info" | "warn" | "error";

Потребитель:

import type { Config, LogLevel } from "./types.js";

Файлы .ts, .tsx, .d.ts

РасширениеСодержимое
.tsTypeScript без JSX
.tsxTypeScript + JSX (React и др.)
.d.tsтолько объявления типов (библиотеки)
// Button.tsx
type Props = { label: string; onClick: () => void };

export function Button({ label, onClick }: Props) {
return <button type="button" onClick={onClick}>{label}</button>;
}

Разбор:

  • В .tsx generic пишут как const List = <T,>(items: T[]) => ... с запятой после T, чтобы не путать с JSX.
  • Прикладной React — 21.md.

Аннотации в функциях

function sum(a: number, b: number): number {
return a + b;
}

type BinaryOp = (a: number, b: number) => number;
const mul: BinaryOp = (a, b) => a * b;

Подробно — 14.md; перегрузки и this там же.


satisfies и синтаксис объектов

type Routes = Record<string, { path: string; private?: boolean }>;

const routes = {
home: { path: "/" },
admin: { path: "/admin", private: true },
} satisfies Routes;

Оператор satisfies проверяет форму, не расширяя вывод полей — см. 10.md. Аннотация : Routes проще, но теряет узкий тип вроде home.path.


Комментарии и JSDoc

TypeScript понимает JSDoc в .js файлах при checkJs / allowJs:

/**
* @param {string} name
* @returns {string}
*/
function greet(name) {
return `Hi, ${name}`;
}

В .ts предпочитайте нативные аннотации; JSDoc — для миграции — 6.md.


Частые ошибки

ОшибкаПричинаЧто делать
Путаница : в объекте и типеодин символ, разный смыслзначение { x: 1 }, тип { x: number }
Union в interfaceнельзя напрямуюtype или extends нескольких
Импорт типа как значенияruntime crashimport type
! вместо проверкинебезопасноnarrowing — 12.md
Generic в .tsx без запятойпарсер JSX<T,>
Дублировать 301 в статьешумссылка на справочник

Практика

  1. Опишите Config через interface, расширьте AppConfig extends Config полем appName.
  2. Опишите ApiResponse как type union success | error.
  3. Разнесите импорт: значения из ./api.js, типы через import type.
  4. Перепишите объект маршрутов с satisfies и проверьте автодополнение в IDE.
  5. Создайте .tsx с компонентом и typed props.

Смежные статьи