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

Type Assertions: as / angle / satisfies / !

Тройка операторов с разной семантикой. as — «верь мне, компилятор» (двусторонне, опасно). satisfies — проверка соответствия без widening, сохраняет литеральные типы. ! (non-null assertion) — снимает null/undefined. На интервью просят пример, где as ломает, а satisfies спасает.

as — двойное приведение, опасно:

const el = document.getElementById('app') as HTMLDivElement;
// если на странице это <span>, то .style.flexDirection упадёт в runtime
// as const — особый случай: фиксирует литералы и readonly
const tuple = [1, 'x'] as const; // readonly [1, 'x']

satisfies сохраняет узкие типы, при этом проверяет соответствие контракту:

type Colors = Record<string, `#${string}`>;
// Без satisfies: тип расширяется до Record<string, `#${string}`>,
// и autocomplete по ключам теряется
const palette1: Colors = { red: '#ff0000', green: '#00ff00' };
// palette1.red.toUpperCase(); // ок, но palette1.blue — ошибки нет (string index)
// С satisfies: точные ключи + проверка значений
const palette2 = {
red: '#ff0000',
green: '#00ff00',
} satisfies Colors;
palette2.red.toUpperCase(); // ок
// palette2.blue; // ошибка: нет такого ключа

! только когда инвариант реально гарантирован, иначе предпочитай явный narrowing:

const m = new Map<string, number>();
m.set('a', 1);
const v = m.get('a')!; // обещаем, что есть; иначе runtime undefined

Итог: satisfies — для литералов и точных типов; as — крайняя мера; ! — только при гарантированном инварианте.