TypeScript: Type Guards и сужение типов

Что такое Type Guard?

Type Guard — механизм сужения (narrowing) типа переменной внутри условного блока на основе проверки во время выполнения. Внутри блока TypeScript уточняет тип значения.

Встроенные способы сужения:

  • typeof — для примитивов
  • instanceof — для классов
  • in — по наличию свойства
  • Array.isArray
  • сравнение с литералом (===, !==)

Пользовательские type guards и оператор is

Функция-предикат с возвращаемым типом arg is Type сообщает компилятору, как сузить тип.

interface Circle { kind: "circle"; radius: number; }
interface Square { kind: "square"; sideLength: number; }
type Shape = Circle | Square;
 
function isCircle(shape: Shape): shape is Circle {
  return shape.kind === "circle";
}
 
if (isCircle(shape)) {
  shape.radius; // здесь shape сужен до Circle
}

is — не самостоятельный оператор; он используется в возвращаемом типе функции для создания пользовательского type guard.


Type Assertions (приведение типов)

Позволяют явно указать тип значения, когда компилятор не может вывести его сам. Это утверждение компилятору, а не проверка во время выполнения.

let someValue: unknown = "Hello, TypeScript!";
let strLength: number = (someValue as string).length;
// Альтернатива: (<string>someValue).length

Overloads (перегрузки функций)

Позволяют задать несколько сигнатур для одной реализации — разные наборы параметров и типы возврата.

function greet(name: string): void;
function greet(firstName: string, lastName: string): void;
function greet(a: string, b?: string): void {
  console.log(b ? `Hello, ${a} ${b}!` : `Hello, ${a}!`);
}
 
greet("John");        // Hello, John!
greet("Jane", "Doe"); // Hello, Jane Doe!