Проверяйте создаваемые значения через satisfies, когда нужен полезный вывод типов. Выбирайте аннотацию, когда переменная должна представлять объявленный контракт. as сообщает компилятору ваше предположение; ни один вариант не проверяет внешние данные во время выполнения.
Определите нужное отношение между значением и типом
Переменная должна быть представлена объявленным контрактом или инициализатор нужно проверить на совместимость с ним? От ответа зависит, насколько удобно использовать конкретную запись. Не выбирайте as только ради исчезновения ошибки: сначала найдите отсутствующее значение или слишком широкий тип.
| Синтаксис | Назначение | Тип переменной |
|---|---|---|
| const x: T = value | Проверить объявление | Объявленный T |
| value satisfies T | Проверить совместимость | Выведенный тип выражения |
| value as T | Утвердить тип | Утверждённый T |
Проверьте карту маршрутов и типы её записей
Проверьте этот отдельный файл в строгом режиме компилятора. Два комментария @ts-expect-error отмечают ожидаемые ошибки: аннотация представляет свойство объединением, а инициализатор satisfies не содержит health. Если строка перестанет быть ошибочной, сама директива вызовет ошибку. checked.home поддерживает строковый метод, а checked.health предоставляет path.
Утверждение типа принимает неполный объект: вывод asserted.health показывает undefined. Недостающий маршрут не появился. Следующий потребитель может упасть, несмотря на убедительный тип. Так выглядит разница между проверкой совместимости и заявлением о знании, которого у компилятора нет.
type RouteName = 'home' | 'health';
type RouteValue = string | { path: string };
type Routes = Record<RouteName, RouteValue>;
const annotated: Routes = {
home: '/', health: { path: '/health' }
};
const checked = {
home: '/', health: { path: '/health' }
} satisfies Routes;
const asserted = { home: '/' } as Routes;
checked.home.toUpperCase();
checked.health.path.toUpperCase();
// @ts-expect-error: the annotated property is a union
annotated.home.toUpperCase();
// @ts-expect-error: health is required
const missing = { home: '/' } satisfies Routes;
// Compiles, but asserted.health is undefined at runtime.
console.log(asserted.health);Не обещайте сохранение всех литералов через satisfies
В примере checked.home выводится как string, а не обязательно как литерал '/'. satisfies сохраняет полезный тип выражения, но контекстная типизация и обычный вывод типов продолжают действовать. Проверяйте конкретный тип нужного свойства вместо общего обещания неизменного вывода.
Для свежего объектного литерала проверка Record с обязательными именами маршрутов также находит лишние ключи с опечатками. Она не превращает структурную систему TypeScript в универсальную проверку точного набора свойств. Перенос значения в промежуточную переменную способен изменить применение проверки лишних свойств.
Добавляйте as const, когда подходят литералы и readonly
Этот отдельный пример сохраняет точный путь home и делает свойства readonly на уровне типов, одновременно проверяя обязательные ключи. Ошибка присваивания добавлена намеренно. Компилируйте пример отдельно от первого: оба объявляют RouteName. В отличие от утверждения Routes, as const задаёт особый вывод типов для литерала.
Выбирайте его, когда ограничения полезны потребителю, а не автоматически для любой конфигурации. Объект не замораживается во время выполнения: если мутации нужно реально запрещать, потребуется отдельная политика JavaScript.
type RouteName = 'home' | 'health';
const routes = {
home: '/', health: '/health'
} as const satisfies Record<RouteName, string>;
const exactHome: '/' = routes.home;
// @ts-expect-error: as const makes this property readonly
routes.home = '/new';Проверяйте внешние данные перед использованием
Ответ HTTP или разобранный JSON может не соответствовать заявленной структуре. Передайте его настоящей проверке как unknown. Функция проверяет только нужное потребителю поле path: для показанного значения возвращает /health, для null или числового пути бросает исключение. Более сложному контракту нужны соответствующие проверки.
Аннотация разобранного значения, утверждение типа маршрута или satisfies для значения с типом any не исследуют содержимое ответа. Явно разделяйте проверку создаваемых значений компилятором и границу доверия к данным во время выполнения.
function readPath(value: unknown): string {
if (
typeof value !== 'object' || value === null ||
!('path' in value) || typeof value.path !== 'string'
) {
throw new Error('Expected an object with a string path');
}
return value.path;
}
console.log(readPath({ path: '/health' }));Упражнение на ревью за десять минут
Добавьте маршрут admin в RouteName и предскажите, какие инициализаторы не пройдут проверку. Верните все обязательные ключи, затем добавьте ключ с опечаткой в свежий литерал satisfies. Сравните типы home в первом примере и варианте с as const. Объясните, почему ни одно решение не доказывает правильность пути из ответа сервера.
Повторите связанные вопросы по TypeScript и опишите каждое решение через его цель и отвергнутую альтернативу. Полезный ответ обозначает контракт и границу проверки во время выполнения, а не только синтаксис.
Коротко
Частые вопросы
satisfies безопаснее, чем as?
Для проверки создаваемого значения satisfies проверяет совместимость с контрактом. as меняет представление компилятора и способен скрыть недостающие данные, как в примере маршрутов. Ни один вариант не проверяет содержимое ответа во время выполнения.
Заменяет ли satisfies аннотации типов?
Нет. Аннотация полезна, когда переменная намеренно должна представлять объявленный контракт. satisfies помогает проверить инициализатор и сохранить более конкретные типы записей.
Делает ли satisfies объект неизменяемым?
Нет. as const может добавить readonly и вывод литеральных типов для создаваемого литерала, но даже он не замораживает объект во время выполнения.
Источники
Источники и редакционная политика
Сведения проверены 4 октября 2026 г. Ссылки рядом с разделами указывают источники фактов и технических объяснений. Выводы, учебные сценарии и рекомендации по подготовке — редакционная работа RecallDeck.
От чтения к воспроизведению
Отрепетируйте полный цикл интервью.
RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.