Погнали дальше про DOOM на TS типах
TL;DR
- infer выводит новый тип из переданного, работает только с extends
- Пример: `Icon${infer Name}` убирает префикс Icon из названий
- Степени двойки заранее записаны в массив — вместо вычисления на лету
- Такой подход ускоряет расчёты и экономит ресурсы
Погнали дальше про DOOM на TS типах
Хочу немного разжевать трюк с
По-русски это можно прочитать как "если переданный тип
То есть мы не знали что за тип вернет
Тут оговорочка,
Собственно, это открывает нам путь к условным выражениям, которые, совместно с концепцией сужения типов позволяют на типах написать хоть тудушку, хоть дум
Еще одна прикольная штука с
В нашем думе это используют чтобы реверснуть строку, например
И еще одна вещь которую хотел бы оттуда подсветить, это предрасчет значений. Почему то в современной разработке об этом забыли и считают все на лету. Но раньше, особенно в условиях ограниченных ресурсов, такое часто использовали.
Так вот. Представьте что вам нужно по заданному параметру что то посчитать. Например, взять степень двойки. Скорее всего, вы в лоб возведете 2 в степень и в большинстве случаев будете правы. Но! Если у вас слишком мало ресурсов или, как здесь, нет умножения, что тогда?
Так как результаты возведения двойки в степень никогда не изменятся, то есть 2^3 всегда будет 8, то мы можем заранее определить набор результатов и просто брать из них как из
Ну а дальшу мы просто
Дальше я этот проект разбирать не вижу смысла, уж больно душные штуки там присутствуют. Но делитесь в комментах или шлите в личку если найдете что то клевое!
Хочу немного разжевать трюк с
infer, так как это довольно непонятная концепция в языке в принципе. Че он дает? Возможность выделить новый тип из переданного. Использовали когда нибудь ReturnType? Вот как выглядит его реализацияtype ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;По-русски это можно прочитать как "если переданный тип
Т это функция ((...args: []) =>), то то что она вернет обзови как R и верни; иначе хз"То есть мы не знали что за тип вернет
Т, но сказали его вытащить как новую "переменную"Тут оговорочка,
infer можно использовать только совместно с extendsСобственно, это открывает нам путь к условным выражениям, которые, совместно с концепцией сужения типов позволяют на типах написать хоть тудушку, хоть дум
Еще одна прикольная штука с
infer. Представьте что у вас есть куча каких то иконок, названия которых начинаются с Icon - IconArrowUp, IconWallet и т.д. Вы хотите определить тип для этой иконки, но не хотите все писать с префиксом. Что приходит на ум? iconName.slice(4)? Зацените как это можно на чистом ts сделатьtype WithoutIconPrefix<IconName> = IconName extends `Icon${infer Name}`
? Name
: IconName;
type Wallet = WithoutIconPrefix<"IconWallet">; // "Wallet"В нашем думе это используют чтобы реверснуть строку, например
И еще одна вещь которую хотел бы оттуда подсветить, это предрасчет значений. Почему то в современной разработке об этом забыли и считают все на лету. Но раньше, особенно в условиях ограниченных ресурсов, такое часто использовали.
Так вот. Представьте что вам нужно по заданному параметру что то посчитать. Например, взять степень двойки. Скорее всего, вы в лоб возведете 2 в степень и в большинстве случаев будете правы. Но! Если у вас слишком мало ресурсов или, как здесь, нет умножения, что тогда?
Так как результаты возведения двойки в степень никогда не изменятся, то есть 2^3 всегда будет 8, то мы можем заранее определить набор результатов и просто брать из них как из
Maptype PowersOfTwo = [
/* 2**0 */ 1,
/* 2**1 */ 2,
/* 2**2 */ 4,
/* 2**3 */ 8,
// ...
/* 2**30 */ 1073741824,
/* 2**31 */ 2147483648,
];Ну а дальшу мы просто
type CubeOfTwo = PowersOfTwo[3]; // 8. Круто же?Дальше я этот проект разбирать не вижу смысла, уж больно душные штуки там присутствуют. Но делитесь в комментах или шлите в личку если найдете что то клевое!
Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.