1. В TypeScript есть утилитарный тип **`Awaited<T>`**, который используется для извлечения типа результата, который выдает промис. Это может быть полезно в ситуациях, где вам нужно работать с типом данных, который асинхронная функция или промис возвращает, не дожидаясь его выполнения. Давайте рассмотрим подробнее ваш пример: ```tsx type MyAwaited<T extends PromiseLike<any>> = Awaited<T>; ``` Здесь вы определяете тип **`MyAwaited`**, который использует утилитарный тип **`Awaited`** от TypeScript. Ваш тип **`MyAwaited`** предназначен для работы с объектами, которые соответствуют интерфейсу **`PromiseLike`**, то есть объектами, которые имеют метод **`then`**. Это позволяет использовать **`MyAwaited`** для обработки объектов, похожих на промисы, но не обязательно являющихся экземплярами реализации **`Promise`**. 2. **`readonly any[]`** позволяет использовать свойство **readonly с массивами, чтобы их типы были сохранены** ```tsx type Concat<T extends readonly any[], U extends readonly any[]> = [...T, ...U] ``` 3. **`Exclude<T,U>`**- дженерик, позволяющий исключать один тип из другого ```tsx type MyExclude<T, U> = Exclude<T, U> ``` 4. **`Infer` in conditional types** Ключевое слово **`Infer`** дополняет условные типы и не может использоваться вне расширения. Это ключевое слово позволяет нам определить переменную внутри нашего ограничения, на которую можно ссылаться или возвращать. `infer` — это ключевое слово в TypeScript, используемое внутри **условных типов** (`Conditional Types`). Оно позволяет "выводить" **`Infer`** типы из других типов, предоставляя способ извлечения информации о типах, которые вы не можете напрямую получить. Перейдем к примеру: ```tsx type TypeA = { id: string } type TypeB = { id: number } type InferType<T> = T extends { id: infer P } ? P extends string ? string : number : any type ResultType1 = InferType<TypeA> // string type ResultType2 = InferType<TypeB> // number type ResultType3 = InferType<object> // any ``` Достаем через аргументы и типизируем их в кортеж, ```tsx type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer F) => any ? F: never ``` ```tsx type ArrayTest <T> = T extends (infer U)[] ? U: string type FnTest <T> = T extends (...args: any[]) => infer R ? R : string type TestObj = ArrayTest<[string, number, 'asdas']>// string | number type TestFn = FnTest<(...args: string[]) => boolean> // boolean ``` 5. **Record** - это утилитный тип TypeScript, который создает объектный тип с заданными ключами и типом значений. Простыми словами: вы говорите TypeScript "создай мне объект, где все ключи будут такими-то, а все значения - такими-то". Представьте ситуацию: у вас есть список имен котов, и для каждого кота нужно хранить информацию (возраст и породу). Вместо того чтобы писать тип вручную, вы можете использовать `Record`, чтобы TypeScript автоматически создал правильный тип объекта. ```ts // Сначала определяем, какие ключи будут у объекта type CatName = "miffy" | "boris" | "mordred"; // Затем определяем, какой тип данных будет храниться в значениях interface CatInfo { age: number; breed: string; } // Record создает тип: { miffy: CatInfo, boris: CatInfo, mordred: CatInfo } const cats: Record<CatName, CatInfo> = { miffy: { age: 10, breed: "Persian" }, boris: { age: 5, breed: "Maine Coon" }, mordred: { age: 16, breed: "British Shorthair" }, }; // Теперь TypeScript знает, что cats.boris существует и имеет тип CatInfo cats.boris; // { age: 5, breed: "Maine Coon" }, ``` 6. **Partial** - это утилитный тип TypeScript, который делает все свойства объекта необязательными. Простыми словами: вы говорите TypeScript "возьми этот тип, но сделай так, чтобы все поля можно было не указывать". Представьте ситуацию: у вас есть тип с обязательными полями, но вам нужно создать объект, где некоторые поля могут отсутствовать (например, при обновлении данных, когда меняете только часть полей). Вместо того чтобы создавать новый тип и вручную добавлять `?` к каждому полю, вы можете использовать `Partial`, чтобы TypeScript автоматически сделал все свойства опциональными. ``` ts interface User { name: string; age: number; } const partialUser: Partial<User> = { name: "Bob", }; // то есть не обязательный все поля не обязательные поэтому мы можем не писать Age ``` 7. **Pick<T, K>** - это утилитный тип TypeScript, который выбирает только указанные свойства из исходного типа. Простыми словами: вы говорите TypeScript "возьми этот тип, но оставь только вот эти поля, остальные убери". Представьте ситуацию: у вас есть большой тип с множеством полей, но для конкретной задачи нужны только несколько из них. Вместо того чтобы создавать новый тип и копировать нужные поля, вы можете использовать `Pick`, чтобы TypeScript автоматически создал тип только с выбранными свойствами. ```ts interface User { name: string; age: number; email: string; } type UserNameEmail = Pick<User, "name" | "email">; const user: UserNameEmail = { name: "Charlie", email: "[email protected]", }; ``` 8. **Omit<T, K>** - это утилитный тип TypeScript, который исключает указанные свойства из исходного типа. Простыми словами: вы говорите TypeScript "возьми этот тип, но убери из него вот эти поля, остальные оставь" Представьте ситуацию: у вас есть тип с полями, которые нужны в одном месте, но не нужны в другом (например, секретные данные, которые нельзя передавать в API). Вместо того чтобы создавать новый тип и вручную перечислять все поля кроме ненужных, вы можете использовать `Omit`, чтобы TypeScript автоматически создал тип без указанных свойств. ```ts interface User { name: string; age: number; email: string; } type UserWithoutEmail = Omit<User, "email">; const user: UserWithoutEmail = { name: "Dave", age: 25, }; ```