Ayub Begimkulov - уроки по JS
3.11K subscribers
29 photos
212 links
По вопросам и деловым предложениям писать на @ayub_begimkulov
Download Telegram
Всем привет!

Продолжаем наш плейлист по TypeScript. В сегодняшнем видео поговорим про такую важную тему, как type guards и type assertions.

Детально разберем, что это такое, когда их использовать, какие есть встроенные type guard’ы и как превратить вашу функцию в type guard или type assertion.

Обязательно оставляйте лайки и фидбэк в комментариях. Также, если видео было полезно, поделитесь им с друзьями, это помогает каналу расти.

https://youtu.be/xsyykEdOQ7E
👍419🔥32💯1🍓1
Всем привет!

После моего последнего видео многие из вас спрашивают о комментарии ^? внутри TS кода, который показывает тип значения, находящегося строкой выше над комментарием.

Данная фича по дефолту работает в TypeScript playground на их официальном сайте. Однако если вы хотите иметь такое же поведение в VSCode - нужно скачать плагин vscode-twoslash-queries.

В целом тут все работает также, как и при наведении мышкой в редакторе. Однако бывает очень удобно при дебаггинге типизации или когда объясняешь какую-нибудь тему другому человеку.

#devtips #typescript
17👍10🔥52💯1🍓1
Всем привет!

Продолжая нашу тему с TS, хочу поделится тем, почему не надо использовать опциональные параметры для колбэков.

Разберу я это на примере обертки над Array.prototype.map, так как о ней меня спрашивали под одним из моих собесов (тот, что “мидл в 19 лет”).

Что бы понять о чем я, давайте взглянем на этот кусок кода:


function map<Item, MappedItem>(
arr: Item[],
mapper: (item: Item, index: number, originalArray: Item[]) => MappedItem
) {
return arr.map(mapper);
}


Собственно, вопрос стоит в том, почему параметры index и originalArray - обязательные, ведь мы не всегда их используем?

Тут давайте попробуем чуть более детально разобрать, что мы говорим такой типизацией TypeScript'у?

Мы говорим, что в колбэк mapper обязательно должны приходить 3 параметра, а не только 1.

Соответсвенно, даже если человек их не использует, никакой ошибки не будет.


map([1, 2, 3], (item) => String(item));


Остальные 2 параметра придут, но они нам в данном случае просто не нужны. Данный код будет нормально работать в браузере или любом другом runtime. Ну и правила типизации мы никак не нарушаем.

Однако если сделать index и originalArray опциональными - мы получим ошибку.


function map<Item, MappedItem>(
arr: Item[],
mapper: (item: Item, index?: number, originalArray?: Item[]) => MappedItem
) {
return arr.map(mapper);
}

map([1, 2, 3], (item, index) => [item, index * 2]);
// ^^^^^
// 'index' is possibly 'undefined'.


Это происходит потому, что мы хотим использовать index, однако типизация map говорит о том, что он не всегда будет передан нам в колбэк. Из-за этого у нас появляется кейс когда index - undefined.

Вообще, в типизации колбэков обычно никогда не нужно использовать опциональные параметры, если же у вас конечно не какой-то странный кейс.

Об это говорится даже в официальном HandBook.

#devtips #typescript
👍44🔥211💯1🍓1
Наткнулся на этой неделе на статью от создателя core-js про open source.

Сам пост пересказывать не буду - можно почитать по ссылке. Но если вкратце, то там говорится про проблемы деньгами.

И когда я глянул на их страницу - то понял, что количество спонсоров и сами спонсоры там явно такие крутые, как в других популярных проектах.

Сейчас, вроде, чуть по больше, но раньше прям вообще грустно было.

Например, тот же babel уже несколько лет почти стоит на месте, после того, как его создатель начал работать над альтернативой на rust.

Но проект, насколько я знаю, регулярно получает деньги (по этому поводу даже был срач в Твиттере как-то, мол деньги идут, а что улучшается?).

И тут интересно, почему же так происходит? Проект же и в правду важен, особенно для публичных сайтов (еком, соцсети, инфо-сайты и тд.).

Мне все-таки кажется, что спонсорство, это скорее способ пропариться в README какого-то проекта.

Например, тот же frontendmasters - я о нем вообще не знал долгое время. Встретил его я, насколько я помню, именно так.

Для купаных компаний тут думаю тоже есть аспект - во первых имидж в глазах разработчиков (“Мы поддерживаем OSS!”). Ну и думаю может какой-то пуш фичей или что-то подобное тоже может происходить.

А что вы думаете по этому поводу? Вы вообще когда-то слышали про core-js?

https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md
🗿951💯1🍓1
Из интересных вещей, на которые я наткнулся на этой неделе, помимо gpt-4 - это вот этот ПР в react.

В нем наконец-то убирают warning про использование useLayoutEefect во время SSR.

В плане use case’ов тут все ясно, если тебе реально нужен замер позиции элемента при первом рендере, чтобы правильно спозиционировать какой-то элемент, то лучше вообще скрывать этот компонент на сервере.

Однако зачастую useLayoutEffect (особенно в библиотеках) используется для синхронизации ref’ов или еще каких-то действий, никак не связанных с замерами.

В итоге все просто пилили костыли по типу useIsomorphicLayoutEffect, просто чтобы не было лишних ворнингов.

В целом, думаю, что решение правильное. Однако есть момент с тем, что для новичков это может быть совсем не понятным. Но тут уже проблема того, насколько хорошая дока.

Да и так думаю, загуглить такое должно быть не сложно (ну или спросить ChatGPT).

А что думаете вы по этому поводу?

#devtips #news
16👍7💯2🍓1
Всем привет!

В комментариях под последними видео несколько раз спрашивали про высшее образование, решил ответить сразу на всех.

Чтобы не томить вас ожиданиями, сразу скажу, что высшего образования у меня нет. И это пока ни разу мне не помешало, за исключением, возможно, поиска первой работы.

Касательно моего отношения, я считаю, что если нету четкой цели зачем вам оно нужно, и какие знания вы хотите там получить - лучше не идти.

Исключение, наверное, можно сделать для топовых универов (ВШЭ, МФТИ и может еще парочку каких-то).

Из того, что слышал, преподают там намного лучше, чем в других местах. Да и статус хотяб эти университеты могут дать.

Но опять же, если вы пойдете на реальную работу и будете сами развиваться в свой сфере на протяжении 4-х лет, то вряд ли знаний у вас будет меньше, чем у выпускника топового универа.

Касательно моей ситуации, я во время последнего года в школе уже начал фрилансить, поэтому после окончания решил пойти на заочное обучение и устроиться на работу.

По итогу на работу устроился, в универ поступил, но за исключением 1-го раза там и не появлялся (вспомнил, что надо аттестат забрать от туда).

Касательно друзей на всю жизнь и нетворкинга, думаю все тоже сомнительно. За 4 года можно и без университета обзавестись хорошей компанией. Но спросить на эту тему не хочу, тут у всех по разному.

В общем, никаких советов тут не даю, сам своему решению пока что рад, а дальше уже время покажет.

Поделитесь в комментариях своей историей (какое образование, где учились и тд.), буду рад почитать.

Всем хорошего вечера!
👍34💯52🍓1
Всем привет!

Вышел еще один ролик по TypeScript. В нем мы разберем, что такое unknown, never, void. И также поговорим про остальные непонятные типы (Boolean, Object, object, Record, {} и тд.).

Подробно разберем, что из себя представляет каждый их этих типов, и когда их использовать.

Обязательно оставляйте лайки, фидбэк комментариях и делитесь с друзьями - это помогает каналу быстрее расти.

https://youtu.be/KMsbIdTYrd4
🔥58👍87💯1🏆1🍓1
Всем привет!

Вышло новое видео про дженерики в TypeScript. Рассмотрим, как с помощью них можно типизировать сложные кейсы в коде.

Также в конце поговорим про новый функционал, добавленный в версии 4.7.

Обязательно оставляйте лайки, фидбэк в комментариях и делитесь с друзьями - это помогает каналу быстрее расти.

https://youtu.be/-AxxfhR95oQ
👍48🔥94💯21🍓1
Всем привет!

Даю апдейт по статусу моей библиотеки для работы c i18n, которую я вынес в отдельный пакет.

Сегодня наконец доделал типизацию для кейсов, когда у вас ключи хранятся в TS файлах. Теперь при включении опции inferParameterTypes библиотека попробует сама подхватить тип ваших {{}} параметров.

Если у нее это по какой-то причине не получится - произойдет fallback на options?: Record<string, string | number>. Если кому интересно - вот ПР.

Также была улучшена интеграция с React. useI18n теперь возвращает не инстанс I18N, а объект-обертку над инстансом. Соотвественно изменения в языке теперь также поведут обновления компонента и для данного хука (раньше было только для useTranslate).

По дальнейшим планам, докинуть в доку хорошие примеры и полный API reference. Буду рад, если покидаете проекты с хорошей документацией в README для вдохновения.

Также планирую добавлять мультиязычность для своего сайти/блога, попробую там поюзать. Наверняка найду какие-то проблемы.

Ну и тесты докинуть надо, но это думаю уже мы сделаем вместе с вами)
👍207🍓1
This media is not supported in your browser
VIEW IN TELEGRAM
Вот пример, чтобы были понятны улучшения, связанные с типизацией.
👍27🔥5💯2🌭1🍌1🍓1🗿1
Всем привет!

Сегодня общался с подписчиком, и он сообщил об одной проблеме в видео про топ 5 ошибок в rtq.

Так вот, проблема заключалась в том, что при экспорте всех экшенов из слайса return type каждого из action creator'ов был void. А при экспорте конкретных - Action.

Вот пример:


// slice.ts
export const { actions: sliceActions } = slice;
export const { someAction } = slice.actions;

// component.ts
const doSomething = () => {
someAction(); // { type: 'string', payload: string[] }
sliceActions.someAction(); // void
}


Понятное дело, что TypeScript так не работает. Да и в моем опыте ни разу такого не было. Но в чем же тогда проблема?

И тут я вспомнил, что webstorm, который использовал человек, да и в целом продукты от JetBrains не используют LSP (language server protocol).

Это значит, что все фишки с автокомплитом/анализом/рефакторингом и тд. делаются самой командой разработчиков редактора, а не командой языка, на котором вы пишите. Да, не все языки сами поддерживают LSP, иногда это бывает и коммюнити решение, в таком случае проблемы могут быть те же.

Так вот, оказалось, что и в правду причина была именно в этом. После того, как проект был открыт в VS Code - все проблемы ушли.

Целью этого поста не является принижение web storm или разжигание войны между фанатами каждого из этих редакторов. Однако иногда нужно учитывать возможность подобных проблем.

Да и в целом, кажется, что LSP дал большой шаг вперед в плане развития редакторов. Когда с помощью плагина ты можешь добавить полноценную поддержку языка в любом редакторе, поддерживающим данный протокол. Думаю VS Code без него не был бы VS Code'ом.

#devtips #ide
15👍82🔥2💯2🍓1
9👍2💯2🏆2🍓1
Всем привет!

Во первых, удивлен и одновременно рад результатам опроса выше.

Изначально не хотел включать atom и sublime, но потом подумал, вдруг тут окажутся фанаты. Но, видимо таковых уже и нет.

Собственно, возвращаясь к теме этого поста. Хотел бы поговорить про throttle и его вариацию, которая может быть очень полезна.

Это вариация - rafThrottle (raf - request animation frame). Вот простая имплементация.


const rafThrottle = fn => {
let rafId = null;

const throttledFn = (...args) => {
if (typeof rafId === 'number') {
return;
}

rafId = requestAnimationFrame(() => {
fn.apply(null, args);
rafId = null;
});
};

throttledFn.cancel = () => {
if (typeof rafId !== 'number') {
return;
}

cancelAnimationFrame(rafId);
};

return throttledFn;
};


Называть эту фукнцию можно, как угодно. Однако смысл ее заключается в том, что переданный в нее колбэк будет вызываться не чаще, чем 1 раз в кадр.

Для чего это нужно?

Данный функционал нужен тогда, когда у вас есть обработчики, обновляющие UI, которые могут быть вызваны большое кол-во раз в секунду (scroll, wheel, mousemove, touchmove и тд.).

Соотвественно, если ваш обработчик срабатывает 150 раз, а кадров показывается только 60, то 90 раз была совершена ненужная работа.

Как уже и сказал, самое часто применение - это драг какого-то элемента, однако есть и много других ситуаций, где такой throttle бывает полезным.

Также, если у вас lodash в проекте, то при использовании throttle и debounce без 2-го аргумента, задержка будет вычислятся на основе requestAnimationFrame.

#devtips #js
28👍20👀5💯21🍌1🍓1💊1
Всем привет!

Наткнулся сегодня на интересную статью в блоге реакт, про то, над чем сейчас работает команда React.

В целом, очень много интересных вещей. Однако меня больше всего заинтересовал React Forget.

Очень интересно, какой код он будет выдавать на выходе. Так как можно придумать много разных кейсов, когда “наивная” мемоизация не совсем подходит.

Взять даже вот такой код:


function getValue({a, b}) {
// ...
}

const Component = ({object}) => {
const result = getValue(object)
}


Очевидный output здесь будет:


function getValue({a, b}) {
// ...
}

const Component = ({object}) => {
const result = useMemo(() => getValue(object), [object]);
}


Хотя хочется видеть:


function getValue({a, b}) {
// ...
}

const Component = ({object}) => {
const result = useMemo(() => getValue({a: object.a, b: object.b}), [object.a, object.b]);
}


Может оно так и будет работать на самом деле. Однако есть большие сомнения касательно прозрачности.

Ну и нету пока понимания, как в такой схеме различные хаки с ref будут работать. Кажется, что подобные трюки станут еще более неочевидными.

В общем, пока нету публичной реализации - сложно что-то понять на 100%.

Буду рад услышать ваше мнение по поводу React Forget и других грядущих фич.

https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023

#devtips #news
11👍5🔥2💯2🍓1
Всем привет!

Вышло еще одно видео про TypeScript.

На этот раз разберем все встроенные utility types, которые есть в TS. Поговорим про то, что они делают, как работают с разными структурами данных, и где их можно применять.

Обязательно оставляйте лайки, фидбэк в комментариях и делитесь видео с друзьями - это помогает каналу быстрее расти.

https://youtu.be/LLG3GFuzdUA
35🔥17👍4💯2🍓1
Всем привет!

В первую очередь, хотел уточнить касательно предыдущего видео? Смотрели его или нет?

Если да, то какие впечатления? Если нет, то почему? По аналитике видео очень плохо идет (как минимум в 2 раза хуже, чем другие).

Вторым моментом хотел спросить про использование React + TypeScript, и с чем у вас чаще всего проблемы? Что хотели бы услышать по этой теме?

На данный момент подготовил презентацию для видео, однако еще не поздно туда что-то добавить.

Касательно видосов, скорее всего на этой неделе ничего больше не выйдет - уже не успею.

Записал на половину видео про тестирование библиотеки i18n, однако потом осознал, что оно получилось очень непонятным.

Скорее всего пушну тесты без видео, а тему тестирования разберем отдельно как-нибудь.

Как-то так. Всем хорошего вечера!
50👍17💯2👎1🍓1
Всем привет!

Хотел поделиться одним советом, который уже много раз помогал как в работе, так и в жизни.

Однако я сам им часто пренебрегаю.

В общем, совет простой - планируйте, прежде чем делать.

И в очередной раз я убедился в данном совете буквально пару дней назад, когда готовил видео по тестам для i18n и поленился сделать для него план.

Казалось, что тема вообще простая и можно начать снимать сразу.

В итоге все закончилось очень странными видео, которые пришлось удалить, даже не начиная монтаж.

Еще один из частых моментов, где этот совет бывает самым полезным - это рабоче задачи и их оценка.

Если вы не знаете чёткий пулл работ, не надо давать четкую оценку.

Обычно я всегда говорю продуктам что-то такое: «сейчас кажется, что займёт Х времени, однако нужно провести ресерч».

И после подготовительной работы уже можно называть более точные сроки.

Да и результат обычно получается более хороший, когда сначала накинешь план. Сразу становится заметно, какой инфы хватает, что еще не готово.

Часто бывает можно отложить задачу на потом, нежели написать половину кода и ждать, пока бек поправит проблему с АПИ.

Понятное дело, что это касается сложных задач, срок которых превышает пару часов.

В общем, примеров тут могу привести много, однако я думаю вы и сами их знаете.

Цель этого поста еще раз напомнить всем (в том числе и себе самому) о таком просто концепте.

Всем хорошего вечера!

#devtips #productivity
👍4714👌5💯2🔥1🍓1
Всем привет!

Наконец-то дошел до того, чтобы написать про слив кода Яндекса и поделится своим мнением.

Про моральную часть самого поступка, политические обстановку за всем этим и влияние на дальнейшее развитие бизнеса говорить не буду. Да и ничего дельного сказать тут не могу.

Однако я хотел бы обсудить тему, которая нам, как разработчикам, интереснее всего - код.

Cразу скажу, что когда есть коммерческий проект с продуктовыми требованиями, дедлайнами и большим количеством разработчиков - идеального кода никак быть не может.

А если проект еще разрабатывался большое кол-во времени, то там скорее всего будет вообще ужас. Я, например, работал на проекте, который был всего на год младше меня).

Данный аспект играет большую роль. Однако есть еще один момент, который как по мне очень сильно влияет на легаси и его нужно учитывать, если хотите идти в большие компании.

Этот момент касается системы оценок и премий. Работает она так, что награждают тебя за какое-то достижение, которые в конечном итоге должно принести бизнесу деньги.

Большие запуски, увеличение конверсии, добавление нового функционала - это то, за что вас будут поощрять.

Однако если вы возьмете и перепишите старые куски с Angular 1 на React - кроме других разработчиков никто вам спасибо не скажет. А могут даже плохую оценку поставить, если не справитесь с основными задачами.

И еще добавьте сюда то, что часто меняются цели бизнеса. Иногда бывает нужно что-то быстро поменять, и понятное дело в такой ситуации никто не будет делать нормально решение. Просто добавит пару костылей и расставит тудушки, чтобы потом пофиксить.

Однако вот это “потом” зачастую никогда не наступает. Так как появляются другие более важные цели, а про то старое, что работает, уже никто и слышать не хочет.

Как только заканчивается продуктовая задача, которая должна была быть сделана вчера, сразу же приходит еще одна такая же. Вот так и набирается снежный ком тех долга.

Решение, которое я понял для себя в такой ситуации - надо делать то, что следует, без апрува от менеджеров и лидов (в пределах разумного конечно же).

Иначе либо выгоришь, либо наберется очень много тех долга, что уже будет совсем неприятно работать.

Для больших рефакторингов такое не сработает, их нужно обязательно обсуждать. Но для небольших и средних - вполне сойдет. Главное все правильно подать.

Опять же, цель этого поста не похейтить Яндекс или другие большие фирмы. Я, как уже и говорил, считаю, что это хорошее место для работы, особенно если работать в офисе.

Однако есть свои особенности, и их нужно понимать. Ну и от отдела и команды тоже много чего зависит.

Всем хорошего вечера!

#devtips #job
30👍13💯5🍓1
Всем привет!

Записал сейчас видео по деталям работы TS и React.

Однако хотел бы более детально поделится изменением в типизации хука useCallback, которые произошли при переходе на 18-ую версию.

Я думаю некоторые из вас могли заметить, что раньше при передаче функции в хук, аргументы по дефолту были типизированны, как any.


const cb = useCallback((arg1, arg2, arg3) => {
arg1; // any
arg2; // any
arg3; // any
}, []);


В целом, это может выглядеть, как нормальное поведение. Но проблема в том, что это так работает даже в strict моде.

Хотя, если я напишу просто функцию, результат будет вот такой:


const testFn = (arg1, arg2, arg3) => {
// ^^^^ ^^^^ ^^^^
// Parameter 'arg1' implicitly has an 'any' type.ts(7006)
};


Так вот, почему же так происходит? Чтобы понять причину, давайте посмотрим на типизацию хука:


function useCallback<T extends (...args: any[]) => any>(
callback: T,
deps: DependencyList
): T;


Происходит так из-за того, что сам useCallback имеет вот такой generic constraint T extends (...args: any[]) => any.

Соотвественно, мы говорим TS, что переданный callback будет являться подтипом (...args: any[]) => any, и если мы не описывать конкретные типы аргументов, то fallback будет происходить на any.

Более наглядный пример для такого поведения будет выглядеть вот так:


const runCb = (fn: (...args: any[]) => any) => {
return fn();
};

runCb((arg1, arg2) => {
arg1; // any
arg2; // any
});


Думаю тут вопросов о том, почему arg1 и arg2 — any нет. Когда мы описываем extends (...args: any[]) => any ситуация происходит примерно такая же.

Собственно, вот как эта проблема была решена в типизации React:


function useCallback<T extends Function>(
callback: T,
deps: DependencyList
): T;


Как видим в качестве constraint'а они воспользовались типом Function, а не (...args: any[]) => any.

Соответственно, такое ограничение не дает никакой информации компилятору для фолбэка. Поэтому TS заставит нас четко описать типы аргументов:


const cb = useCallback((arg1, arg2, arg3) => {
// ^^^^ ^^^^ ^^^^
// Parameter 'arg1' implicitly has an 'any' type.ts(7006)
}, []);


Как вы помните, я сам не советовал использовать тип Function, однако теперь я нашел ему дельное применение.

Всем хорошего вечера!

#devtips #typescript
25👍19🔥2💯2👌1🍓1
Друзья, есть мысли о том, чтобы переснять плейлист по хукам, так как материал очень полезный, однако он был подан не самым лучшим образом (как с точки зрения объяснений, так и с точки зрения качества видео).

Идея заключается в том, чтобы не просто переснять существующие ролики, а полностью переупаковать материал.

Некоторым хукам уделить большие внимания, объяснить все по лучше и дать больше наглядных примеров. А некоторые видео думаю можно объединить в одно, так как материала там мало, нужно просто подать информацию получше.

Так вот, хотел узнать, насколько вам это интересно? В особенности тем, кто уже смотрел старые видео.

Так как плейлист на данный момент уже есть, однако по просторам, кажется, что многие видео почти не смотрятся уже год. Да и комменты новые все только и говорят про плохой звук).
105👍43❤‍🔥4💯2👌1🍓1