🌍 Привет мир! 👋
🌍 Привет мир! 👋
Скоро Новый год 🎄 и это заключительное чтиво в уходящем 2024, поговорим про TypeScript, а конкретно про infer.
🚀 Мотивация
Не сказать что тема очень популярная, но понимание работы infer keyword, позволит создавать более гибкие и адаптивные типы, кроме того появится способность к чтению типов которые предоставляются сторонними библиотеками.
⁉️ Что такое infer
Infer keyword в TypeScript используется в conditional types для создания типа из другого типа. Это может быть удобно для создания общих типов, которые работают со многими различными типами входных данных.
⚒️ База
Просто пример, который приоткроет замысел infer.
Infer используется только в рамках
Тип T (переданный как generic type, в примере это
📝 Рабочий пример
Данный кейс я решал недавно у себя на рабочем проекте, поэтому ловите прям с “пылу с жару”.
Есть какой-то исторически образованный
✏️ Мы пишем новый функционал, и есть необходимость в создании функции, которая в качестве параметра принимает значение ключа
🫵 Кстати, а вы знаете что вернет такая функция logRole → (void)? Если нет, пишите в комментариях, сделаю подробный разбор на этот кейс в следующей статье о TypeScript.
Не переживаем, решение есть и оно (клевое === не костыльное).
❓Что происходит в типе
📌 T extends { role: infer U }: Проверяется, является ли тип T объектом, который содержит поле
📌 infer U: Получаем тип значения, находящегося в поле
📌 ? U : never: Если условие выполняется (то есть если T имеет поле
👇 Как пользоваться ?
📌 typeof dictionary: Получаем тип
📌 keyof typeof dictionary: Извлекаем все ключи объекта
📌 (typeof dictionary)[keyof typeof dictionary]: Происходит выборка всех значений типа из объекта
‼️ Как итог с помощью
👇Важная информация👇
📌 Многие утилиты в
📌 В рамках одного
💬 Делитесь своим мнением в комментариях👇! Если вам понравилась статья, не забудьте поставить лайк! 👍
#TYPESCRIPT
Скоро Новый год 🎄 и это заключительное чтиво в уходящем 2024, поговорим про TypeScript, а конкретно про infer.
🚀 Мотивация
Не сказать что тема очень популярная, но понимание работы infer keyword, позволит создавать более гибкие и адаптивные типы, кроме того появится способность к чтению типов которые предоставляются сторонними библиотеками.
⁉️ Что такое infer
Infer keyword в TypeScript используется в conditional types для создания типа из другого типа. Это может быть удобно для создания общих типов, которые работают со многими различными типами входных данных.
⚒️ База
Просто пример, который приоткроет замысел infer.
let num = 1;
type GetType<T> = T extends infer N ? N : never;
type ResultType = GetType<typeof num>; // number
Infer используется только в рамках
conditional statement , и только в extends части. Если проговорить словами что здесь происходит, то выглядит это так:Тип T (переданный как generic type, в примере это
number) присваивается переменной N и поскольку условие T extends infer N всегда истинно, то условный тип всегда будет выводить N (number), что равносильно T (number) .📝 Рабочий пример
Данный кейс я решал недавно у себя на рабочем проекте, поэтому ловите прям с “пылу с жару”.
Есть какой-то исторически образованный
dictionary, он явно не идеальный, но что есть, то есть. Кстати выбран способ создания через as const и неспроста, Почему? Ну очевидно, читаем, я уже писал про это =)const dictionary = {
agent: {
password: 'agentPassword',
role: 'agentRole',
},
candidate: {
password: 'candidatePassword',
role: 'candidateRole',
},
contact: {
role: 'contactRole',
},
} as const;
✏️ Мы пишем новый функционал, и есть необходимость в создании функции, которая в качестве параметра принимает значение ключа
role. И не хотелось бы, просто поставить тип string.const logRole = (role: string) => {
console.log(`role: ${role}`)
}
🫵 Кстати, а вы знаете что вернет такая функция logRole → (void)? Если нет, пишите в комментариях, сделаю подробный разбор на этот кейс в следующей статье о TypeScript.
Не переживаем, решение есть и оно (клевое === не костыльное).
type RoleTypeField<T> = T extends { role: infer U } ? U : never;
❓Что происходит в типе
📌 T extends { role: infer U }: Проверяется, является ли тип T объектом, который содержит поле
role.📌 infer U: Получаем тип значения, находящегося в поле
role, и временно обозначаем его как U.📌 ? U : never: Если условие выполняется (то есть если T имеет поле
role), то типом RoleTypeField<T> будет тип U, представляющий значение поля role. Если условие не выполняется, результат будет never (или проще говоря объект будет скипнут) .👇 Как пользоваться ?
type roleType = RoleTypeField<(typeof dictionary)[keyof typeof dictionary]>
const logRole = (role: roleType) => {
console.log(`role: ${role}`)
}
logRole('agentRole')
// ваш аргумент просто песня
logRole('большеЛайков')
// Argument of type '"большеЛайков"' is not assignable
// to parameter of type 'roleType'.
📌 typeof dictionary: Получаем тип
dictionary.📌 keyof typeof dictionary: Извлекаем все ключи объекта
dictionary в виде объединения строковых литералов. Получаем 'agent' | 'candidate' | 'contact' .📌 (typeof dictionary)[keyof typeof dictionary]: Происходит выборка всех значений типа из объекта
dictionary.{
readonly password: "agentPassword";
readonly role: "agentRole";
} | {
readonly password: "candidatePassword";
readonly role: "candidateRole";
} | {
readonly password: "contactPassword";
}
‼️ Как итог с помощью
RoleTypeField получаем типы значений ключа role.type roleType = "agentRole" | "candidateRole"
👇Важная информация👇
📌 Многие утилиты в
TS уже имплементированы при помощи infer (ReturnType, Parameters и др.)📌 В рамках одного
extends можно делать несколько infertype FS<T> = T extends [infer F, infer S, ...any[]] ? [F S] : never
💬 Делитесь своим мнением в комментариях👇! Если вам понравилась статья, не забудьте поставить лайк! 👍
#TYPESCRIPT

Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.