077 Вводное видео
Служебные типы - это упрощение тех сложных манипуляций с типами из прошлой главы. Они предоставляют готовый функционал для работы с типами в ТС
078 Partial, Required, Readonly
У нас есть есть три дженерика, которые позволяют быстро отредактировать модификаторы доступности и обязательности ключей.
Partial
- делает все свойства в объекте необязательными для заполненияRequired
- делает все свойства в объекте необязательными для заполненияReadonly
- все свойства объекта можно заполнить только при создании и далее только просматривать- Сочетание дженериков - можно комбинировать выбранные дженерики, чтобы модифицировать доступность более гибко
interface User {
name: string;
age?: number;
address: string;
}
// Partial
type partial = Partial<User>;
const personPartial: partial = {}; // Нет обязательных полей
// Required
type required = Required<User>;
const personRequired: required = {
name: 'string',
age: 22, // Обязательно
address: 'string',
};
// Readonly
type readonlyP = Readonly<User>;
const personReadonly: readonlyP = {
name: 'string',
age: 22,
address: 'string',
}
personReadonly.name = 'John'; // Error
// Сочетание дженериков
type requiredReadonly = Required<Readonly<User>>;
const personRequiredReadonly: requiredReadonly = {
name: 'string',
age: 22, // Обязательно
address: 'string',
};
personReadonly.name = 'John'; // Error
Все данные инструменты построены под капотом на мапах. Partial представляет из себя мапу, которая на все ключи накидывает необязательность. Required
делает все ключи обязательными через “-?
”. Readonly
уже навешивает на все ключи readonly
модификатор
079 Pick, Omit, Extract, Exclude
Первые два дженерика - Omit
и Pick
- представляют из себя мапы, которые возвращают нам только нужные значения интерфейса в тип.
Omit
- выкидывает ненужное свойство из интерфейса и хранит в тайпе результат модификацииPick
- берёт только нужные значения из интерфейса
interface PaymentPersistence {
id: number,
sum: number,
from: string,
to: string,
}
type PaymentWithoutId = Omit<PaymentPersistence, 'id'>; // выкинет свойство id
type PaymentRequisits = Pick<PaymentPersistence, 'from' | 'to'>; // Берёт только 'from' и 'to'
Далее уже идут дженерики, основанные на кондишеналах внутри.
Extract
- вытаскивает из вложенного юнион-типа только те свойства, которые удовлетворяют типу данных, который был передан вторым аргументом.Exclude
- исключает из юнион-тайпа все те значения, которые равны указанному типу во втором аргументе
Конкретно в нашем примере, Extract говорит, что нам нужно достать только свойства, тип которых будет строкой
interface PaymentPersistence {
id: number,
sum: number,
from: string,
to: string,
}
type PaymentWithoutId = Omit<PaymentPersistence, 'id'>;
type PaymentRequisits = Pick<PaymentPersistence, 'from' | 'to'>;
// sum не попадёт в выборку
type ExtractEx = Extract<'from' | 'to' | PaymentWithoutId, string>;
// В выборку попадёт только PaymentWithoutId, а 'from' и 'to' будут исключены
type ExcludeEx = Exclude<'from' | 'to' | PaymentWithoutId, string>;
И так выглядят эти дженерики под капотом
080 ReturnType, Parameters, ConstructorParameters
И дальше у нас идут дженерики, которые позволяют достать типы из функции.
ReturnType<>
- возвращает тип возвращаемого значения из функцииParameters<>
- возвращает кортеж типов аргументов функции
class User {
constructor(
public id: number,
public name: string
) {
}
}
function getData(id: number): User {
return new User(id, 'John');
}
// Вернёт то, что возвращает функция
type RT = ReturnType<typeof getData>; // User
type RT2 = ReturnType<() => void>; // void
type RT3 = ReturnType<<T>() => T>; // unknown
type RT4 = ReturnType<<T extends string>() => T>; // string
// Вернёт то, что находится в параметрах функции в виде кортежа
type PT = Parameters<typeof getData>; // === [id:number]
type first = PT[0]; // === number
Так же доступна и такая запись для быстрого обращения к первому параметру
type PT = Parameters<typeof getData>[0];
И так же у нас есть подобные дженерики для работы с классами:
ConstructorParameters
- возвращает кортеж параметров конструктора классаInstanceType
- вернёт тип инстанса
class User {
constructor(
public id: number,
public name: string
) {
}
}
// [id: number, name: string]
type CP = ConstructorParameters<typeof User>;
// User
type IT = InstanceType<typeof User>;
081 Awaited
Дженерик Awaited<>
показывает нам полный результат ожидания Promise
- а именно тот тип, который должен вернуть Promise
type A = Promise<string>; // Promise<string>
type A2 = Awaited<Promise<string>>; // string
type A3 = Awaited<Promise<Promise<string>>>; // string
И примерно так выглядит Awaited
изнутрянки. Тут уже используются вложенные кондишенелы для реализации проверки. Тут уже через условия и рекурсию реализована возможность получать конечный возвращаемый тип промиса и его вложений
Первый кейс использования: нам нужно вернуть с бэка на фронт менюшку и поработать с ней. Конкретно тут удобство заключается в том, что мы можем поработать с этой менюшкой, как с определённым типом данных.
ReturnType
вернёт нам Promise<IMenu[]>
, а уже сам Awaited
вернёт IMenu[]
interface IMenu {
name: string;
url: string;
}
async function getMenu(): Promise<IMenu[]> {
return [
{
name: 'Analythics',
url: 'http...'
}
];
}
type R = Awaited<ReturnType<typeof getMenu>>; // IMenu[]
Ну и так же в этом примере представлен второй кейс использования авэйтеда. Он тут в качестве типа подставляется автоматически в качестве указания типа ретёрна из функции. Тут возвращается массив результатов асинхронных функций
async function getArray<T>(x: T) {
return [await x];
}