Синтаксис и пунктуация 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 / interface | User | исчезает |
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: когда что
| Задача | Предпочтение |
|---|---|
| Форма объекта, публичный API | interface |
| Union, tuple, mapped types | type |
| Расширение объекта | 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приNodeNext— 9.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
| Расширение | Содержимое |
|---|---|
.ts | TypeScript без JSX |
.tsx | TypeScript + 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>;
}
Разбор:
- В
.tsxgeneric пишут как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 crash | import type |
! вместо проверки | небезопасно | narrowing — 12.md |
Generic в .tsx без запятой | парсер JSX | <T,> |
| Дублировать 301 в статье | шум | ссылка на справочник |
Практика
- Опишите
Configчерезinterface, расширьтеAppConfig extends ConfigполемappName. - Опишите
ApiResponseкакtypeunionsuccess | error. - Разнесите импорт: значения из
./api.js, типы черезimport type. - Перепишите объект маршрутов с
satisfiesи проверьте автодополнение в IDE. - Создайте
.tsxс компонентом и typed props.
Смежные статьи
- Типы — примитивы, utility types
- Функции — сигнатуры, overloads
- Классы —
implements - Подключение — модули,
NodeNext - Справочник — Справочник — интерфейсы и модули
- JS: 17