Что такое оператор `satisfies` в TypeScript?

MiddleTypeScript · Frontend·Обновлено 7 августа 2026
Коротко
Оператор satisfies проверяет, что значение соответствует указанному типу, но при этом сохраняет более точный выведенный тип переменной — в отличие от явной аннотации типа, которая расширяет тип до указанного.

Оператор satisfies в TypeScript

Оператор satisfies появился в TypeScript 4.9 и решает классическую проблему: как одновременно получить проверку типа и сохранить точный выведенный тип.

Проблема без satisfies

При явной аннотации типа TypeScript расширяет тип переменной до указанного, теряя точную информацию:

type Colors = 'red' | 'green' | 'blue';
type Palette = Record<Colors, string | [number, number, number]>;

// Явная аннотация — тип каждого значения становится string | [number, number, number]
const palette: Palette = {
  red: [255, 0, 0],
  green: '#00ff00',
  blue: [0, 0, 255],
};

// Ошибка: TypeScript не знает, что red — это массив, а не строка
const redChannel = palette.red.toUpperCase(); // нет ошибки, но упадёт в рантайме

Решение с satisfies

const palette = {
  red: [255, 0, 0],
  green: '#00ff00',
  blue: [0, 0, 255],
} satisfies Palette;

// TypeScript знает точный тип каждого поля
const redChannel = palette.red[0];          // OK — number
const greenUpper = palette.green.toUpperCase(); // OK — string

// Но проверка типа всё равно работает
const wrong = {
  red: [255, 0, 0],
  green: '#00ff00',
  // Ошибка: отсутствует обязательное поле blue
} satisfies Palette;

Ключевые отличия от аннотации типа

Аннотация : Type satisfies Type
Проверка типа Да Да
Расширение типа Да Нет
Сохраняет выведенный тип Нет Да
Влияет на тип переменной Да Нет

Практические сценарии

1. Конфигурационные объекты:

type Config = {
  port: number;
  host: string;
  flags: Record<string, boolean>;
};

const config = {
  port: 3000,
  host: 'localhost',
  flags: { debug: true, verbose: false },
} satisfies Config;

// TypeScript точно знает тип flags.debug — boolean, не unknown
const isDebug: boolean = config.flags.debug;

2. Сужение union-типов в значениях:

type Route = {
  path: string;
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
};

const routes = [
  { path: '/users', method: 'GET' },
  { path: '/users', method: 'POST' },
] satisfies Route[];

// method выведен как 'GET' | 'POST', а не просто string

Важный нюанс

satisfies — это операция проверки на этапе компиляции, она не влияет на рантайм-поведение и не генерирует никакого JavaScript-кода. Это чисто статический инструмент TypeScript.

Что хочет услышать интервьюер

Понимание разницы между `satisfies` и явной аннотацией типа — что оба проверяют тип, но аннотация расширяет тип переменной, а `satisfies` сохраняет точный выведенный тип

Знание версии появления оператора (TypeScript 4.9) и базового синтаксиса

Умение объяснить практический кейс: конфигурационные объекты, словари с union-типами в значениях

Понимание того, что `satisfies` не генерирует код в рантайме — это только компиляторная проверка

Способность привести пример, где `satisfies` решает реальную проблему потери типа при явной аннотации

Пример: Сравнение аннотации типа и satisfies

type Theme = {
  primary: string | [number, number, number];
  secondary: string | [number, number, number];
};

// С аннотацией — тип расширяется
const themeAnnotated: Theme = {
  primary: '#ff0000',
  secondary: [0, 128, 255],
};
// themeAnnotated.primary — string | [number, number, number]
// .toUpperCase() вызовет ошибку TS, хотя значение — строка

// С satisfies — тип сохраняется точным
const themeSatisfies = {
  primary: '#ff0000',
  secondary: [0, 128, 255],
} satisfies Theme;
// themeSatisfies.primary — string (точный тип!)
const upper = themeSatisfies.primary.toUpperCase(); // OK
// themeSatisfies.secondary — [number, number, number] (точный тип!)
const blue = themeSatisfies.secondary[2]; // OK — number

Пример: Реальный кейс: конфигурация приложения

type AppConfig = {
  env: 'development' | 'production' | 'test';
  port: number;
  database: {
    host: string;
    port: number;
  };
};

// satisfies гарантирует соответствие AppConfig,
// но сохраняет литеральный тип 'development'
const config = {
  env: 'development',
  port: 3000,
  database: {
    host: 'localhost',
    port: 5432,
  },
} satisfies AppConfig;

// config.env выведен как 'development', а не string
const isDev = config.env === 'development'; // TS знает, что это true

// Ошибка компиляции — отсутствует поле database
const badConfig = {
  env: 'production',
  port: 8080,
} satisfies AppConfig; // Property 'database' is missing

Типичные ошибки

Путают `satisfies` с аннотацией типа — считают, что это синонимы и не понимают разницы в поведении вывода типов

Думают, что `satisfies` изменяет тип переменной, хотя она остаётся с точным выведенным типом

Не знают версию TypeScript, в которой появился оператор, и не могут сказать, что он относительно новый

Не понимают, что `satisfies` ничего не делает в рантайме — ошибочно считают его runtime-валидатором

Не могут привести практический пример и объясняют оператор только абстрактно

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее