TypeScript поддерживает оператор typeof не только для времени исполнения (как в JavaScript), но и на этапе компиляции для вывода типа выражения. Это позволяет получить тип уже объявленной переменной, функции или структуры объекта, что делает типизацию гибкой и снижает вероятность дублирования и рассинхронизации типов.
Первоначально в JavaScript оператор typeof использовался для определения типа значения в рантайме. TypeScript расширил этот механизм — теперь typeof на этапе компиляции создает ссылку на тип значения переменной или результата функции. Это крайне полезно при работе со сложными структурами, конфигами, а также при переиспользовании типа между модулями.
При ручном объявлении типа легко ошибиться: поменять определение структуры и забыть обновить type- или interface-объявление, либо неправильно скопировать типы между объектами. Это ведет к рассинхронизации кода и ошибкам выполнения. При использовании typeof тип выводится динамически и всегда соответствует актуальной структуре данных.
Для объявления переменной с типом, соответствующим уже существующей структуре или константе, применяют оператор typeof:
const config = { host: "localhost", port: 8080, }; let serverCfg: typeof config; // Тип serverCfg такой же, как у config
Для типизации функции, возвращающей определённую структуру:
function makeUser() { return { id: 1, name: "Alex" }; } type User = ReturnType<typeof makeUser>; // User: {id: number; name: string;}
Ключевые особенности:
typeof в TS возвращает тип значения переменной или результата выражения на этапе компиляции.ReturnType, Parameters), а также с keyof для получения перечня ключей объекта.Выполняется ли оператор typeof в TypeScript на этапе исполнения?
Нет, типовой typeof работает только при компиляции, не попадая в рантайм-код, хотя оператор JavaScript typeof существует и в runtime.
Может ли typeof использоваться для вывода типа свойств класса?
Да, но только если свойство уже объявлено как статичное или с начальным значением, иначе будет ошибка. Для private/public protected — учитываются только публичные свойства/методы.
Есть ли разница между 'let x: typeof y;' и 'let x = y;'?
С типовой точки зрения — в обоих случаях компилятор выведет тип автоматически. Однако, 'typeof' можно использовать для написания деклараций типов без инициализации или для более сложных комбинаций с утилитарными типами.
typeof для привычного js-проверки типа typeof x === 'string' — это runtime, а не компилируемый тип.В проекте описывается большой объект настроек приложения отдельно как тип, отдельно как переменная. При изменении структуры забывают обновить тип, что приводит к ошибкам работы API.
Плюсы: Гибкая работа с типами, можно переопределять типы через type или interface
Минусы: Большой риск рассинхронизации структуры и типов, плохая поддерживаемость
Использование typeof для получения актуального типа структуры объекта при объявлении новых переменных и при генерации типа для API-интерфейса.
Плюсы: Тип всегда совпадает со значением, низкая вероятность ошибки, хорошее автодополнение
Минусы: Если объект очень сложный, итоговый тип может быть запутанным на чтение для новичков