TypeScript 5: новые возможности — оператор satisfies, декораторы, const-параметры типа
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。
Хотите разобраться, чем TypeScript 5 отличается от предыдущих версий и какие новые возможности стоит использовать в реальных проектах? В этой статье подробно разобраны ключевые нововведения TypeScript 5.0–5.4: оператор satisfies, стандартные декораторы, параметры типов с const, расширение нескольких файлов tsconfig и многое другое.
Обзор TypeScript 5
| Параметр | Значение |
|---|---|
| Основные новые функции | Оператор satisfies, стандартные декораторы, параметры типа const, расширение нескольких файлов tsconfig, улучшения enum и namespace |
| Функции с наибольшим практическим влиянием | satisfies, новые декораторы |
| Дата начала мажорной версии | Март 2023 |
TypeScript 5 — это мажорная версия, вышедшая в марте 2023 года. Начиная с 5.0, серия последовательно развивалась вплоть до 5.4. Наиболее значимые изменения — введение стандартных декораторов и оператора satisfies.
Хронология релизов:
| Версия | Дата | Ключевые функции |
|---|---|---|
| TypeScript 5.0 | 2023-03 | satisfies, const type parameters, расширение нескольких tsconfig |
| TypeScript 5.1 | 2023-06 | Независимые типы getter/setter, улучшения JSX |
| TypeScript 5.2 | 2023-08 | Ключевые слова using/await using, метаданные декораторов |
| TypeScript 5.3 | 2023-11 | Import Attributes, улучшенное сужение типов |
| TypeScript 5.4 | 2024-03 | Утилита NoInfer, сохранение сужения типов в замыканиях |
1. Оператор satisfies — полное практическое руководство
Оператор satisfies — одна из наиболее инновационных функций TypeScript 5.0. Он преодолевает ограничения традиционных утверждений типов: проверяет соответствие ограничениям типа, сохраняя при этом вывод типа.
Проблема со старым подходом
// ❌ Проблема старого подхода
type Color = "red" | "green" | "blue";
type ColorMap = Record<string, string | number[]>;
// Утверждение as: проверка типа есть, вывода нет
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255]
} as ColorMap;
// palette.red теперь выводится как string | number[]
// Для использования .map() нужно утверждение типа
palette.red.map(x => x); // Ошибка! У string | number[] нет mapИспользование satisfies
// ✅ Оператор satisfies
type Color = "red" | "green" | "blue";
type ColorMap = Record<Color, string | number[]>;
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255]
} satisfies ColorMap;
// Проверка типа есть, литеральный вывод тоже есть
palette.red.map(x => x); // ✅ number[] сохраняется
palette.green.toUpperCase(); // ✅ string сохраняется
const wrong = { purple: "purple" } satisfies ColorMap; // ❌ Ошибка: "purple" не является ColorПрактические паттерны использования
Паттерн 1: Валидация объектов ответа API
interface ApiConfig {
baseUrl: string;
timeout: number;
retries: number;
}
// satisfies: проверка типа + точный вывод значений
const config = {
baseUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
} satisfies ApiConfig;
// config.timeout — это 5000 (литеральный тип), а не просто number
type TimeoutType = typeof config.timeout; // 5000Паттерн 2: Определение маршрутов
type Route = {
path: string;
component: React.ComponentType;
auth?: boolean;
};
const routes = [
{ path: "/", component: Home },
{ path: "/dashboard", component: Dashboard, auth: true },
] satisfies Route[];
// routes[0].path сохраняется как "/" (литерал), проверка Route тоже проходитПаттерн 3: Объекты мультиязычных переводов
type TranslationKey = "hello" | "goodbye" | "welcome";
type Translations = Record<TranslationKey, string>;
const ko = {
hello: "Привет",
goodbye: "До свидания",
welcome: "Добро пожаловать",
} satisfies Translations;
const en = {
hello: "Hello",
goodbye: "Goodbye",
// welcome отсутствует → ошибка компиляции! ✅
} satisfies Translations;2. Стандартные декораторы — полная реализация TC39 Stage 3
TypeScript 5.0 поддерживает стандартные декораторы TC39 Stage 3, отдельные от давно используемых экспериментальных декораторов (experimentalDecorators).
Ключевые отличия
| Категория | Экспериментальные декораторы | Стандартные декораторы (5.0+) |
|---|---|---|
| Активация | experimentalDecorators: true | Включены по умолчанию (tsconfig не требуется) |
| Соответствие стандартам | Собственная реализация | TC39 Stage 3 |
| Порядок выполнения | Обратный | Прямой |
| Метаданные | emitDecoratorMetadata | Использует Symbol.metadata |
| Поддержка функций | Ограниченная | Только классы |
Декораторы классов
// ✅ Стандартный декоратор TypeScript 5
function sealed(target: typeof SealedClass) {
Object.seal(target);
Object.seal(target.prototype);
}
@sealed
class SealedClass {
greet() { return "Hello!"; }
}Декораторы методов
function log(target: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
return function (this: any, ...args: any[]) {
console.log(`[${methodName}] вызван, аргументы:`, args);
const result = target.call(this, ...args);
console.log(`[${methodName}] возвращает:`, result);
return result;
};
}
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2);
// [add] вызван, аргументы: [1, 2]
// [add] возвращает: 3Декораторы аксессоров
function readonly(target: any, context: ClassAccessorDecoratorContext) {
return {
set() {
throw new Error(`${String(context.name)} доступен только для чтения.`);
}
};
}
class Config {
@readonly
accessor version = "1.0.0";
}
const cfg = new Config();
console.log(cfg.version); // "1.0.0"
cfg.version = "2.0.0"; // ❌ ОшибкаМетаданные декораторов (TypeScript 5.2)
// Использование Metadata API
function validate(target: any, context: ClassFieldDecoratorContext) {
context.metadata[context.name] = { required: true };
}
class UserForm {
@validate
name!: string;
@validate
email!: string;
}
// Чтение метаданных
const metadata = UserForm[Symbol.metadata];
console.log(metadata); // { name: { required: true }, email: { required: true } }3. Параметры типа const
Модификатор const, добавленный в TypeScript 5.0, усиливает вывод типов для обобщённых функций.
// ❌ Старый подход
function identity<T>(value: T): T {
return value;
}
const result = identity(["a", "b", "c"]);
// result: string[] (литерал утрачивается)
// ✅ Параметр типа const
function identityConst<const T>(value: T): T {
return value;
}
const result2 = identityConst(["a", "b", "c"]);
// result2: readonly ["a", "b", "c"] (литерал сохраняется!)Практическое применение: построитель маршрутов
function createRoute<const Path extends string>(path: Path) {
return { path, url: () => `https://app.example.com${path}` };
}
const homeRoute = createRoute("/");
// homeRoute.path: "/" (литерал сохраняется)
const dashRoute = createRoute("/dashboard");
// dashRoute.path: "/dashboard" (литерал сохраняется)4. Расширение нескольких файлов tsconfig
Начиная с TypeScript 5.0, extends в tsconfig.json может принимать массив.
// tsconfig.json
{
"extends": [
"@tsconfig/strictest/tsconfig.json",
"@tsconfig/node18/tsconfig.json",
"./custom.tsconfig.json"
],
"compilerOptions": {
"outDir": "dist"
}
}Раньше для наследования нескольких файлов нужно было создавать цепочку, теперь множественное наследование обрабатывается сразу с помощью массива.
5. Ключевые слова using / await using (TypeScript 5.2)
Это новые ключевые слова для управления ресурсами, аналогичные конструкции try-with-resources в Java. Они автоматически высвобождают ресурсы после завершения блока — например, закрывают файлы, соединения с базой данных или сетевые сессии.
// Объект с Symbol.dispose
class DatabaseConnection {
connect() { console.log("Подключено к БД"); }
[Symbol.dispose]() { console.log("Соединение с БД закрыто"); }
}
// using: автоматический вызов dispose при выходе из области видимости
function queryDatabase() {
using conn = new DatabaseConnection();
conn.connect();
// ... выполнение запросов
// conn[Symbol.dispose]() вызывается автоматически при возврате
}6. Утилита NoInfer (TypeScript 5.4)
NoInfer предотвращает использование конкретного параметра типа как основы для вывода типов.
// ❌ Без NoInfer: TypeScript выводит тип из обоих параметров
function setDefault<T>(values: T[], defaultValue: T): T {
return values.length > 0 ? values[0] : defaultValue;
}
setDefault(["a", "b"], "c"); // OK
setDefault(["a", "b"], 42); // OK... но нежелательно
// ✅ С NoInfer: вывод только из первого параметра
function setDefaultStrict<T>(values: T[], defaultValue: NoInfer<T>): T {
return values.length > 0 ? values[0] : defaultValue;
}
setDefaultStrict(["a", "b"], "c"); // OK: "c" — string
setDefaultStrict(["a", "b"], 42); // Ошибка: 42 не является string💡 Практические наблюдения
На практике разработчики, переходящие на TypeScript 5, чаще всего сталкиваются с вопросом: «Когда использовать satisfies, а когда as?» Ответ прост: as заглушает проверку типов, тогда как satisfies проводит полную валидацию, сохраняя точный вывод. В реальных проектах satisfies особенно полезен для конфигурационных объектов, где важно одновременно гарантировать корректность типа и сохранить литеральные значения. Что касается декораторов: если вы используете NestJS или подобные фреймворки с experimentalDecorators, не торопитесь с миграцией — старые и новые декораторы несовместимы по поведению. Переходите постепенно, начав с новых модулей.
Часто задаваемые вопросы (FAQ)
В1. Какая функция TypeScript 5 наиболее важна?
О. Оператор satisfies, стандартные декораторы и параметры типа const оказывают наибольшее практическое влияние.
В2. Когда следует использовать оператор satisfies?
О. Используйте его, когда нужно проверить соответствие объекта определённым требованиям типа, сохраняя при этом точный вывод.
В3. В чём разница между satisfies и as?
О. as — это утверждение типа, а satisfies — валидация типа, поэтому он безопаснее выявляет некорректные структуры.
В4. Декораторы TypeScript 5 отличаются от старых?
О. Стандартные декораторы следуют процессу TC39 и ведут себя иначе, чем существующие experimentalDecorators.
В5. Зачем нужны параметры типа const?
О. Они сохраняют вывод литерального типа в обобщённых функциях, позволяя создавать более точные типы.
В6. Что проверить перед обновлением до TypeScript 5?
О. Проверьте совместимость tsconfig, использование декораторов, инструменты сборки, ESLint и типы библиотек.
Источник: Экономическая статистика Банка Кореи
🔧 Related Free Tools
Похожее
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT6 способов зарабатывать дополнительный доход с ChatGPT — практическое и проверенное руководство по монетизации на 2026 годUSD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT2026 ChatGPT vs Claude vs Gemini — Сравнение производительности, цен и способов использования AI-чат-ботовUSD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
ITОптимизация скорости сайта в 2026 году — как достичь Core Web Vitals 90+USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...