Основы Typescript
2026-02-26 22:28 Diff

В JavaScript возможно работать с объектами и классами одинаковым образом. При этом не нужно опираться ни на наследование, ни на интерфейсы. Нужны только ожидаемые поля и методы. Такой подход называют утиной типизацией (duck typing). Если что-то ходит как утка и крякает как утка — значит, это утка:

В языках как Java нам бы потребовалось определить интерфейс, после отдельно имплементировать его для классов User и Admin. А в параметрах метода форматирования тип аргумента был бы этим интерфейсом.

Другой вариант — написать метод с перегрузкой для этих двух случаев. Языки с таким поведением используют номинативную типизацию (nominative typing).

Чтобы организовать подход утиной типизации в Java, нужно написать много дополнительного кода.

Чтобы упростить переход с JavaScript на TypeScript и использовать проверки до выполнения кода, был выбран подход структурной типизации. С ней мы и познакомимся в этом уроке.

С помощью структурной типизации мы можем легко переписать наш пример на TypeScript:

При этом структурная типизация не защищает нас от наличия дополнительных полей в объекте:

В структурной типизации об объектном типе можно думать, как об описании структуры, которое накладывает ограничения на присваиваемые значения. Или как о множестве объектов, которые могут быть присвоены переменной с таким типом.

Чем меньше полей в объектном типе, тем менее специфичное ограничение накладывается на присваиваемое значение. На множествах это означает, что объектный тип с дополнительными полями будет подмножеством объектного типа без этих полей. Если говорить о сужении и расширении типа в объектных типах, то дополнительные поля сужают тип.

Аналогично операциям со множествами для объектных типов можно сформировать понимание пересечения и объединения в структурной типизации.

При объединении | мы расширяем тип — увеличиваем число допустимых значений для типа. А при пересечении & — сужаем. Так мы уменьшаем число допустимых значений:

Попробуйте ответить, что будет, если использовать в пересечении два объектных типа с одинаковым именем поля, но с отличающимися типами. Это распространенная ошибка по невнимательности или из-за недостаточного понимания типов как множеств.

Ответ При пересечении объектных типов, если встречаются поля с одинаковыми именами, то они должны быть совместимы — иметь одинаковый тип. Иначе будет ошибка компиляции, потому что итоговый тип будет `never`.