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

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

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

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


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

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


Что добавляет 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 — Архитектура компиляции TypeScript и runtime.


Пунктуация — 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; подробнее в Операторы и условные ветвления в TypeScript.


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

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

interface Employee extends Person {
department: string;
}

Разбор:

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

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


interface и type — когда что

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

typeалиас любого типа: примитив, union, intersection, tuple, mapped types, условные типы.

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

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

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

Разбор:

  • Для React props и DTO (объект передачи данных с API) часто берут interface; для результата операцииtype с union.
  • В Объекты и классы в TypeScript класс может implements interface.
  • На уровне типов interface и type для объектов часто взаимозаменяемы — выбирайте единый стиль в команде.
Правило команды

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


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

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

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

Разбор:

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

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

Импорт типов — подключение только контрактов TypeScript без значений в runtime. После компиляции такие импорты удаляются — в .js не остаётся лишних зависимостей.


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

export type { User };
ФормаСмысл
import type { T } from "…"только тип T
import { type T, fn } from "…"смешанный импорт (TS 4.5+)
export type { T }реэкспорт типа
import { type T }inline type import в одной строке с значениями

Разбор:

  • import type гарантирует: импорт удалится при компиляции — нет лишних зависимостей в JS.
  • Смешанный импорт value + type — TypeScript 4.5+.
  • В runtime-модулях путь часто с .js при NodeNextФорматы и подключение TypeScript.
  • С verbatimModuleSyntax / importsNotUsedAsValues компилятор строже требует import type для чисто типовых импортов — Компиляция.

Ошибка "User only refers to a type, but is being used as a value" — вы импортировали тип как значение; используйте import type или разделите импорты.


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

// 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 — TypeScript и React.

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

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

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

Подробно — Функции в TypeScript; перегрузки и this там же.


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

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

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

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


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

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

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

В .ts предпочитайте нативные аннотации; JSDoc — для миграции — Рекомендации по разработке на TypeScript.


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

ОшибкаПричинаЧто делать
Путаница : в объекте и типеодин символ, разный смыслзначение { x: 1 }, тип { x: number }
Union в interfaceнельзя напрямуюtype или extends нескольких
Импорт типа как значенияruntime crashimport type
! вместо проверкинебезопасноnarrowing — Операторы и условные ветвления в TypeScript
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.

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