Привет, друзья! Представляю вашему вниманию перевод нескольких статей из серии Mastering TypeScript, посвященных углубленному изучению TypeScript. 
 T называется параметром общего типа (generic type parameter). Это заменитель (placeholder) настоящего (actual) типа, передаваемого функции. Суть такая: берем тип, определенный пользователем, и привязываем (chain) его к типу параметра функции и типу возвращаемого функцией значения. 
 Так что все-таки означает T? T означает тип (type). На самом деле, вместо T можно использовать любое валидное название. Часто в сочетании с T используются такие общие переменные, как K, V, E и др. 
 Разумеется, мы не ограничены одним параметром типа — их может быть сколько угодно: 
 При вызове функции identity можно явно определить действительный тип параметра типа. Или можно позволить TypeScript самостоятельно сделать вывод относительного него: 
 Приходилось ли вам использовать утилиты типов Exclude, Extract, NonNullable, Parameters и ReturnType? Все эти утилиты основаны на условных типах (conditional types): Здесь представлена лишь часть процесса

 Краткая справка: 
 Названные утилиты используются для следующих целей: Примеры использования этих утилит: 
 Синтаксис условных типов: T, U, X и Y — заменители типов (см. выше). Сигнатуру можно понимать следующим образом: если T может быть присвоен U, возвращается тип X, иначе возвращается тип Y. Это чем-то напоминает тернарный оператор в JavaScript. 
 Как условные типы используются? Рассмотрим пример: 
 Утилита IsString позволяет определять, является ли действительный тип, переданный в качестве параметра типа, строковым типом. В дополнение к этому, с помощью условных типов и условных цепочек (conditional chain) можно определять несколько типов за один раз: 
 Условная цепочка похожа на тернарные выражения в JS: 
 Вопрос: что будет, если передать TypeName объединение (union)? 
 Почему типы T10 и T11 возвращают объединения? Это объясняется тем, что TypeName — это распределенный (distributed) условный тип. Условный тип называется распределенным, если проверяемый тип является "голым" (naked), т. е. не обернут в массив, кортеж, промис и т. д. 
 В случае с распределенными условными типами, когда проверяемый тип является объединением, оно разбивается на несколько веток в процессе выполнения операции: 
 Рассмотрим пример: 
 Если параметр типа обернут в условный тип, он не будет распределенным, поэтому процесс не разбивается на отдельные ветки. Рассмотрим поток выполнения (execution flow) встроенной утилиты Exclude: 
 Пример реализации утилиты с помощью условных и связанных (mapped, см. Заметка о Mapped Types и других полезных возможностях современного TypeScript) типов: 
 Данные утилиты позволяют легко извлекать атрибуты функциональных и нефункциональных типов, а также связанные с ними объектные типы из типа User. Приходилось ли вам использовать утилиты типов Partial, Required, Pick и Record? 
 Внутри всех этих утилит используется оператор keyof. В JS ключи объекта извлекаются с помощью метода Object.keys: В TS это делается с помощью keyof: После получения ключа объектного типа, мы можем получить доступ к типу значения, соответствующему данному ключу, с помощью синтаксиса, аналогичного синтаксису доступа к свойству объекта: В приведенном примере используется тип индексированного доступа (indexed access type) для получения типа определенного свойства типа User. Как keyof используется на практике? Рассмотрим пример: Функция getProperty принимает 2 параметра: объект (obj) и ключ (key), и возвращает значение объекта по ключу. Перенесем данную функцию в TS: 
 В сообщениях об ошибках говорится о том, что obj и key имеют неявные типы any. Для решения проблемы можно явно определить типы параметров: 
 Получаем другую ошибку. Для правильного решения следует использовать параметр общего типа (generic) и keyof: Определяем 2 параметра типа: T и K. extends применяется, во-первых, для ограничения (constraint) типа, передаваемого T, подтипом объекта, во-вторых, для ограничения типа, передаваемого K, подтипом объединения ключей объекта. При отсутствии ключа TS генерирует следующее сообщение об ошибке: 
 Оператор keyof может применяться не только к объектам, но также к примитивам, типу any, классам и перечислениям. 
 Рассмотрим поток выполнения (execution flow) утилиты Partial: 
 
 Рассмотрим несколько полезных примеров использования оператора typeof. 1. Получение типа объекта 
 Объект man — это обычный объект JS. Для определения его типа в TS можно использовать type или interface. Тип объекта позволяет применять встроенные утилиты типов, такие как Partial, Required, Pick или Readonly, для генерации производных типов. Для небольших объектов ручное определение типа не составляет труда, но для больших и сложных объектов с несколькими уровнями вложенности это может быть утомительным. Вместо ручного определения типа объекта можно прибегнуть к помощи оператора typeof: Person["address"] — это тип индексированного доступа (indexed access type), позволяющий извлекать тип определенного свойства (address) из другого типа (Person). 2. Получение типа, представляющего все ключи перечисления в виде строк В TS перечисление (enum) — это специальный тип, компилирующийся в обычный JS-объект: 
 Поэтому к перечислениям также можно применять оператор typeof. Однако в случае с перечислениями, typeof обычно комбинируется с оператором keyof: 
 3. Получение типа функции Другим примером использования typeof является получение типа функции (функция в JS — это тоже объект). После получения типа функции можно воспользоваться встроенными утилитами типов ReturnType и Parameters для получения типа возвращаемого функцией значение и типа ее параметров: 
 4. Получение типа класса 
 В приведенном примере createPoint — это фабричная функция, создающая экземпляры класса Point. С помощью typeof можно получить сигнатуру конструктора класса Point для реализации проверки соответствующего типа. При отсутствии typeof в определении типа конструктора возникнет ошибка: 
 6. Получение более точного типа Использование typeof в сочетании с утверждением const (const assertion), представленным в TS 3.4, позволяет получать более точные (precise) типы: 
 Надеюсь, что вы, как и я, нашли для себя что-то интересное. Благодарю за внимание и happy coding!  JavaScript Developer