TypeScript. Оператор keyof
Оператор
Смотрим на функцию
Функция работает с двумя типами:
При
#typescript #дженерики
Оператор
keyof
в TypeScript принимает любой объектный тип и возвращает новый тип, который представляет собой объединение ключей полученного типа (строк или чисел). type Point = {Можно даже использовать его с примитивными типами, в этом случае получим набор имен встроенных методов:
x: number,
y: number
}
type PointKeys = keyof Point; // 'x' | 'y'
type NumberKeys = keyof number; // "toString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" | "toLocaleString"Пример использования (ограничение обобщенных типов)
Смотрим на функцию
getProperty
. Она получает объект, имя свойства и возвращает значение этого свойства у объекта.Функция работает с двумя типами:
T
(объект) и K
(имя свойства). При
K
- существующее у объекта свойство, то есть один из ключей объекта.K extends keyof TПри вызове функции компилятор получает аргументы и выводит их типы.
getProperty(developer, 'pay');- тип
T
- это Staff
- тип K
- это keyof T
, а точнее "name" | "salary"
Компилятор смотрит на второй аргумент. Его тип pay
и он не может быть присвоен объединению ключей Staff
.#typescript #дженерики
👍2
Асинхронный рендеринг в React 18
Видео (рус.): https://www.youtube.com/watch?v=vRq9UtVhP_8&t=3500s
В видео два доклада, нужный начинается на 58 минуте.
Небольшой доклад (~ 20 мин) о новом (относительно) конкурентном режиме в React. Можно смотреть на увеличенной скорости.
Начинается с краткого вступления о том, как вообще был задуман этот режим, зачем, и как он постепенно внедрялся в библиотеку (React Fiber, хуки - это все этапы долгого пути).
В целом конкуррентный режим - это не треды, не отдельные потоки выполнения кода, а просто "планировщик", который может выбирать, какую из актуальных задач выполнять, ориентируясь на ее приоритет.
Затем на живых примерах разбираются три фичи конкурентного режима:
В целом доклад очень понятный, позволит составить общее представление о Concurrent React, если еще не.
#ссылки #concurrentmode
Видео (рус.): https://www.youtube.com/watch?v=vRq9UtVhP_8&t=3500s
В видео два доклада, нужный начинается на 58 минуте.
Небольшой доклад (~ 20 мин) о новом (относительно) конкурентном режиме в React. Можно смотреть на увеличенной скорости.
Начинается с краткого вступления о том, как вообще был задуман этот режим, зачем, и как он постепенно внедрялся в библиотеку (React Fiber, хуки - это все этапы долгого пути).
В целом конкуррентный режим - это не треды, не отдельные потоки выполнения кода, а просто "планировщик", который может выбирать, какую из актуальных задач выполнять, ориентируясь на ее приоритет.
Затем на живых примерах разбираются три фичи конкурентного режима:
Suspense
, useTransition
, useDeferredValue
. Все это как раз способы указать приоритет различных задач.В целом доклад очень понятный, позволит составить общее представление о Concurrent React, если еще не.
#ссылки #concurrentmode
YouTube
Онлайн митап «Асинхронный рендеринг в React 18 и принципы практичного рефакторинга»
Тайминг митапа:
3:38 О компании "Синимекс"
6:15 Рефакторинг. Как поджечь свой велосипед и не пожалеть об этом?
58:16 Чудеса асинхронного рендеринга
1:30:46 Квиз
Telegram-каналы наших информационных партнёров:
ITMeeting - https://yangx.top/ITMeeting
FrontEndDev…
3:38 О компании "Синимекс"
6:15 Рефакторинг. Как поджечь свой велосипед и не пожалеть об этом?
58:16 Чудеса асинхронного рендеринга
1:30:46 Квиз
Telegram-каналы наших информационных партнёров:
ITMeeting - https://yangx.top/ITMeeting
FrontEndDev…
🔥2
Используйте коллбэк-рефы вместо useEffect
Статья (англ.): https://tkdodo.eu/blog/avoiding-use-effect-with-callback-refs
Статья рассматривает и критикует обращение к рефам в React внутри хука
Это рабочий подход, но он имеет и свои минусы, главный среди которых - привязка вызова к рендеру компонента, а не к отрисовке самого элемента. Если поле ввода выводится в компоненте не сразу (условный рендеринг), то это не сработает.
Было бы здорово привязать вызов функции именно к отрисовке самого поля ввода - и для этого приходят на помощь функциональные рефы. На самом деле в проп
При удалении элемента функция вызывается снова, на этот раз с параметром
Ну и чтобы функция не создавалась и не запускалась при каждом перерендеринге, ее нужно обернуть в
В статье, кроме того, есть пример использования этого подхода для получения метрик элемента.
Старый пост про коллбэк-рефы: https://yangx.top/react_junior/122
#рефы #хуки #статьи
Статья (англ.): https://tkdodo.eu/blog/avoiding-use-effect-with-callback-refs
Статья рассматривает и критикует обращение к рефам в React внутри хука
useEffect
. Например, так мы часто реализуем установку фокуса на поле ввода.
useEffect(function() {
inputRef.current?.focus();
}, []);
Это рабочий подход, но он имеет и свои минусы, главный среди которых - привязка вызова к рендеру компонента, а не к отрисовке самого элемента. Если поле ввода выводится в компоненте не сразу (условный рендеринг), то это не сработает.
Было бы здорово привязать вызов функции именно к отрисовке самого поля ввода - и для этого приходят на помощь функциональные рефы. На самом деле в проп
ref
можно передавать не только объект, созданный через React.useRef
, но и обычную функцию. Она вызывается как раз в момент отрисовки элемента и получает сам элемент в качестве параметра.
ref={ function(node) {
node?.focus();
} }
При удалении элемента функция вызывается снова, на этот раз с параметром
null
.Ну и чтобы функция не создавалась и не запускалась при каждом перерендеринге, ее нужно обернуть в
useCallback
.В статье, кроме того, есть пример использования этого подхода для получения метрик элемента.
Старый пост про коллбэк-рефы: https://yangx.top/react_junior/122
#рефы #хуки #статьи
tkdodo.eu
Avoiding useEffect with callback refs
Interacting with DOM nodes doesn't necessarily need useEffect
👍4
Визуальный гайд по рендерингу в React
Серия статей (англ.):
- Часть 1. It Always Re-renders
- Часть 2. Props
- Часть 3. useMemo
- Часть 4. useCallback
- Часть 5. Context
- Часть 6. DOM
Вспоминаем, как происходит рендер и перерендер в React.
1) При изменении состояния компонента, он ререндерится.
2) Если ререндерится родительский компонент, ререндерятся и все его потомки, если только они не созданы с помощью React.memo.
3) При изменении пропсов, компонент ререндерится (даже если он создан с помощью React.memo). Важно при этом помнить про ссылочные типы данных (объекты, массивы, функции), которые могут выглядеть одинаково, но не быть при этом равны. Например, если передать в проп дочернего компонента анонимную функцию, то при каждом ререндеринге родителя это будет уже другая функция, поэтому потомок тоже будет перерендериваться, даже если обернут в React.memo. Чтобы этого избежать, используем хуки useMemo и useCallback.
4) Если компонент подписан на контекст, то при изменении контекста он ререндерится.
5) На самом деле при изменении контекста (глобального состояния приложения), перерендеривается корневой элемент приложения, а значит и все его потомки. Чтобы избежать этого, можно оборачивать первого потомка AppContext.Provider в React.memo.
6) Если в провайдер контекста передается ссылочный тип данных, который меняется при каждом рендеринге корневого элемента, то все будет работать как с пропсами в пункте 3. Нужно такой контекст мемоизировать.
В последней части вспоминаем, что перерендеринг не обязательно ведет к обновлению DOM-дерева. Если визуально компонент не изменился, он не будет обновлен, React вносит лишь минимально необходимые точечные изменения.
#статьи #оптимизация #контекст #подкапотом
Серия статей (англ.):
- Часть 1. It Always Re-renders
- Часть 2. Props
- Часть 3. useMemo
- Часть 4. useCallback
- Часть 5. Context
- Часть 6. DOM
Вспоминаем, как происходит рендер и перерендер в React.
1) При изменении состояния компонента, он ререндерится.
2) Если ререндерится родительский компонент, ререндерятся и все его потомки, если только они не созданы с помощью React.memo.
3) При изменении пропсов, компонент ререндерится (даже если он создан с помощью React.memo). Важно при этом помнить про ссылочные типы данных (объекты, массивы, функции), которые могут выглядеть одинаково, но не быть при этом равны. Например, если передать в проп дочернего компонента анонимную функцию, то при каждом ререндеринге родителя это будет уже другая функция, поэтому потомок тоже будет перерендериваться, даже если обернут в React.memo. Чтобы этого избежать, используем хуки useMemo и useCallback.
4) Если компонент подписан на контекст, то при изменении контекста он ререндерится.
5) На самом деле при изменении контекста (глобального состояния приложения), перерендеривается корневой элемент приложения, а значит и все его потомки. Чтобы избежать этого, можно оборачивать первого потомка AppContext.Provider в React.memo.
6) Если в провайдер контекста передается ссылочный тип данных, который меняется при каждом рендеринге корневого элемента, то все будет работать как с пропсами в пункте 3. Нужно такой контекст мемоизировать.
В последней части вспоминаем, что перерендеринг не обязательно ведет к обновлению DOM-дерева. Если визуально компонент не изменился, он не будет обновлен, React вносит лишь минимально необходимые точечные изменения.
#статьи #оптимизация #контекст #подкапотом
Alex Sidorenko
A Visual Guide to React Rendering - It Always Re-renders | Alex Sidorenko
Contrary to popular belief, by default, react component doesn't care whether its props changed or not. It will always re-render when its parent renders.
👍4
TypeScript. Преобразование к типу
Преобразование к типу (Type assertion) - явное указание типа значения какого-либо выражения.
Есть два способа сделать это:
1) Тип указывается в угловых скобках перед выражением.
2) Тип указывается после оператора
Пример на картинке.
Если явно не указать тип явно, компилятор будет ругаться, так как результатом работы метода
#typescript
Преобразование к типу (Type assertion) - явное указание типа значения какого-либо выражения.
Есть два способа сделать это:
1) Тип указывается в угловых скобках перед выражением.
2) Тип указывается после оператора
as
после выражения.Пример на картинке.
Если явно не указать тип явно, компилятор будет ругаться, так как результатом работы метода
getElementById
может быть не только HTML-элемент, но и null
.#typescript
👍4🔥1
TypeScript. ReadonlyArray
Можно определить массив, элементы которого нельзя изменять (добавлять новые, удалять существующие, перезаписывать).
Определяется как обычный массив с указанием типа.
Кроме того, можно использовать уже знакомую нам утилиту readonly.
У таких массивов нет методов, которые изменяют массив.
#typescript
Можно определить массив, элементы которого нельзя изменять (добавлять новые, удалять существующие, перезаписывать).
Определяется как обычный массив с указанием типа.
Кроме того, можно использовать уже знакомую нам утилиту readonly.
У таких массивов нет методов, которые изменяют массив.
#typescript
👍4
TypeScript. Заголовочные файлы
Если в проекте используются глобальные переменные, компилятор TypeScript не будет ничего о них знать и не сможет скомплировать программу.
Чтобы помочь ему, необходимо объявить эти переменные, то есть описать их для TypeScript.
Эта строчка сообщает компилятору, что в коде может встретиться переменная с именем
Так же можно объявлять функции, объекты различной структуры и даже классы:
Эти объявления обычно выносятся в отдельные заголовочные (декларативные) файлы с расширением
Если мы компилируем отдельный файл (
#typescript
Если в проекте используются глобальные переменные, компилятор TypeScript не будет ничего о них знать и не сможет скомплировать программу.
console.log(globalVar); // Cannot find name 'globalVar'
Чтобы помочь ему, необходимо объявить эти переменные, то есть описать их для TypeScript.
declare let globalVar: string;
Эта строчка сообщает компилятору, что в коде может встретиться переменная с именем
globalVar
и типом string
. Теперь он сможет оперировать ей.Так же можно объявлять функции, объекты различной структуры и даже классы:
declare function sum(a: number, b: number): number;
declare const user: {name: string, age: number, print: ()=> void};
declare class Person{
name: string;
age: number;
constructor(name: string, age: number);
display(): void;
}
Эти объявления обычно выносятся в отдельные заголовочные (декларативные) файлы с расширением
.d.ts
.Если мы компилируем отдельный файл (
tsc app.ts
), то компилятор не сможет самостоятельно найти заголовочные файлы, которые используются, поэтому их нужно подключить с помощью директивы reference
:#typescript
🔥1
TypeScript. Заголовочные файлы для популярных библиотек
Основная область применения заголовочных файлов - использование крупных готовых библиотек вроде jQuery или, например, Knockout (моя боль 😅).
То есть мы используем переменные и функции библиотеки, о которых TypeScript ничего не знает, например,
Звучит очень страшно, но к счастью, для большинства популярных инструментов эта работа уже сделана.
В репозитории DefinitelyTyped можно найти заголовочные файлы для огромного количества библиотек.
Их можно установить через npm:
Чтобы компилятор знал, где искать эти заголовочные файлы, нужно в файл tsconfig.json добавить опцию
#typescript
Основная область применения заголовочных файлов - использование крупных готовых библиотек вроде jQuery или, например, Knockout (моя боль 😅).
То есть мы используем переменные и функции библиотеки, о которых TypeScript ничего не знает, например,
$
. Их нужно описать.Звучит очень страшно, но к счастью, для большинства популярных инструментов эта работа уже сделана.
В репозитории DefinitelyTyped можно найти заголовочные файлы для огромного количества библиотек.
Их можно установить через npm:
npm install --save-dev @types/jquery
Чтобы компилятор знал, где искать эти заголовочные файлы, нужно в файл tsconfig.json добавить опцию
compilerOptions.typeRoots
:{
compilerOptions: {
//...
typeRoots: [ 'node_modules/@types' ]
}
}
#typescript
GitHub
GitHub - DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.
The repository for high quality TypeScript type definitions. - DefinitelyTyped/DefinitelyTyped
👍1
Стратегии перехода на TypeScript
Статья (рус., перевод): https://webformyself.com/strategii-perexoda-na-typescript/
В статье перечислены три стратегии:
- JS +TS в одном проекте, постепенное переключение
- добавление типов через JSDoc с последующим переключением на TS
- снэпшот-тесты для больших проектов
Мне очень захотелось подключить TS в мой текущий рабочий проект (на Knockout).
Решено было использовать первую стратегию и идти сверху вниз (или снизу вверх, как посмотреть 🤔, в общем переводить на TS мелкие файлы, которые импортируются более крупными).
Для этого потребовалось внести изменения в сборку. Для TS-файлов добавился ts-loader для Webpack. Получается, что при импорте TS-файла он сначала обрабатывается лоадером, а затем дальше участвует в сборке как обычный JS в составе файла, который его импортировал.
#typescript #проверкатипов #подключение #ссылки
Статья (рус., перевод): https://webformyself.com/strategii-perexoda-na-typescript/
В статье перечислены три стратегии:
- JS +TS в одном проекте, постепенное переключение
- добавление типов через JSDoc с последующим переключением на TS
- снэпшот-тесты для больших проектов
Мне очень захотелось подключить TS в мой текущий рабочий проект (на Knockout).
Решено было использовать первую стратегию и идти сверху вниз (или снизу вверх, как посмотреть 🤔, в общем переводить на TS мелкие файлы, которые импортируются более крупными).
Для этого потребовалось внести изменения в сборку. Для TS-файлов добавился ts-loader для Webpack. Получается, что при импорте TS-файла он сначала обрабатывается лоадером, а затем дальше участвует в сборке как обычный JS в составе файла, который его импортировал.
#typescript #проверкатипов #подключение #ссылки
Webformyself
Стратегии перехода на TypeScript
Три стратегии перехода с JavaScript на TypeScript: смешанные базы, добавление информации о типах в обычные файлы, снэпшот-тестирование
👍4
Что такое K, T и V в TypeScript Generics
Статья (англ.): https://medium.com/frontend-canteen/what-are-k-t-and-v-in-typescript-generics-9fabe1d0f0f3
На пальцах объясняется, что это за буковки в угловых скобках. Можно даже не читать, просто посмотреть анимашки, из них все становится понятно.
В двух словах, это плейсхолдеры для типов, которые будут определены только при вызове функции.
То есть изначально мы не знаем точно, какой тип придет, но знаем закономерности его обработки внутри функции. Например, если придет строка, то и вернется строка.
Буковки могут быть любые,
Еще популярны:
-
-
-
#ссылки #typescript #дженерики
Статья (англ.): https://medium.com/frontend-canteen/what-are-k-t-and-v-in-typescript-generics-9fabe1d0f0f3
На пальцах объясняется, что это за буковки в угловых скобках. Можно даже не читать, просто посмотреть анимашки, из них все становится понятно.
В двух словах, это плейсхолдеры для типов, которые будут определены только при вызове функции.
То есть изначально мы не знаем точно, какой тип придет, но знаем закономерности его обработки внутри функции. Например, если придет строка, то и вернется строка.
Буковки могут быть любые,
T
просто используется чаще всего (T
- Type).Еще популярны:
-
K
- Key-
V
- Value-
E
- Element#ссылки #typescript #дженерики
👍2🔥1
Mapped Types в TypeScript
Статья (англ.): https://javascript.plainenglish.io/using-typescript-mapped-types-like-a-pro-be10aef5511a
В статье очень подробно разбираются Mapped Types - такие типы, которые берут один тип с определенным набором полей и создают из него другой тип с таким же набором полей. При этом может изменяться типизация этих полей или их настройки (например, обязательность).
Например, если у нас есть тип:
то из него можно получить:
Это самый банальный пример, на самом деле там все намного интереснее.
К посту прилагается картинка, на которой изображено "внутреннее устройство" утилит
#typescript #подкапотом #ссылки
Статья (англ.): https://javascript.plainenglish.io/using-typescript-mapped-types-like-a-pro-be10aef5511a
В статье очень подробно разбираются Mapped Types - такие типы, которые берут один тип с определенным набором полей и создают из него другой тип с таким же набором полей. При этом может изменяться типизация этих полей или их настройки (например, обязательность).
Например, если у нас есть тип:
type User = {
name: string;
password: string;
address: string;
phone: string;
};
то из него можно получить:
type UserPartial = {
name?: string;
password?: string;
address?: string;
phone?: string;
};
Это самый банальный пример, на самом деле там все намного интереснее.
К посту прилагается картинка, на которой изображено "внутреннее устройство" утилит
Partial
, Required
, Readonly
и Pick
, которые в общем и являются Mapped Types. На первый взгляд выглядит страшно, но статья подробно объясняет, как это работает, и как самостоятельно создавать типы с похожей функциональностью. #typescript #подкапотом #ссылки
👍2🔥1
Своими словами:
в этих типах мы используем обобщения (дженерики).
Например, утилита
Она берет все ключи исходного типа (
Но к каждому полю добавлен значок
А типы полей ровно те же самые, что и у исходного типа -
В итоге получается точно такая же структура, но каждое поле в ней необязательное.
#typescript
в этих типах мы используем обобщения (дженерики).
Например, утилита
Partial
принимает некий тип T
, неизвестно, какой конкретно, и на его основе создает новый тип.Она берет все ключи исходного типа (
keyof T
) и делает их своими ключами. Каждый конкретный ключ обозначается типом P
. То есть P
- это каждый ключ типа T
, и у нового типа будут те же самые поля.Но к каждому полю добавлен значок
?
- то есть поле становится опциональным, необязательным.А типы полей ровно те же самые, что и у исходного типа -
T[P]
. Это обычный синтаксис доступа к свойствам объекта, но тут он применяется к типу.В итоге получается точно такая же структура, но каждое поле в ней необязательное.
#typescript
👍2🔥1
Typescript. Утилиты. Часть 2 (Exclude, Extract, NonNullable)
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Exclude
Принимает два параметра:
-
-
Результатом является объединение, в которое входят все члены
Extract
Принимает два параметра:
-
-
Результатом является объединение, в которое входят все члены
NonNullable
Принимает один параметр
#typescript
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Exclude
Принимает два параметра:
-
Union
-
ExcludedMembers
- члены, которые нужно исключить из Union
Результатом является объединение, в которое входят все члены
Union
, кроме тех, которые могут быть присвоены в ExcludedMembers
Extract
Принимает два параметра:
-
Type
-
Union
- объединение типов, которые нужно отобрать из Type
Результатом является объединение, в которое входят все члены
Type
, которые одновременно могут быть присвоены в Union
NonNullable
Принимает один параметр
Type
и выбрасывает из него null
и undefinded
.#typescript
👍2🔥1
Typescript. Утилиты. Часть 3 (Parameters, ReturnType)
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Утилиты
Возьмем функцию:
В утилиту нужно передать тип этой функции, а не ее значение:
Утилита
Утилита
#typescript
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Утилиты
Parameters
и ReturnType
работают с функциями и могут, соответственно, получать типы входных параметров или возвращаемого значения.Возьмем функцию:
function add(num1: number, num2: number): number {
return num1 + num2;
}
В утилиту нужно передать тип этой функции, а не ее значение:
typeof add
Утилита
Parameters
вернет кортеж их типов входных аргументов: [num1: number, num2: number]
Утилита
ReturnType
вернет тип возвращаемого значения:number
#typescript
👍3
TypeScript. Условные типы
Статья (англ): https://javascript.plainenglish.io/use-typescript-conditional-types-like-a-pro-7baea0ad05c5
Утилиты Exclude, Extract, NonNullable, Parameters, and ReturnType используют "условные типы" (Conditional Types).
В статье подробно разбирается их внутреннее устройство, разобравшись с которым можно создавать свои похожие утилиты.
Общий синтаксис условных типов выглядит так:
Берется некий тип
Простейшая утилита
Она просто определяет, является ли переданный тип строкой.
Но можно делать и намного более сложные вещи.
Распределенные условные типы
Если передать в утилиту объединение типов, на выходе тоже можно получить объединение, потому что операция выполняется для каждого члена объединения - это называется _распределенные условные типы__ (distributed conditional type).
Но это работает только для "голых" типов, не обернутых в массивы/кортежи/промисы.
#typescript #ссылки #подкапотом
Статья (англ): https://javascript.plainenglish.io/use-typescript-conditional-types-like-a-pro-7baea0ad05c5
Утилиты Exclude, Extract, NonNullable, Parameters, and ReturnType используют "условные типы" (Conditional Types).
В статье подробно разбирается их внутреннее устройство, разобравшись с которым можно создавать свои похожие утилиты.
Общий синтаксис условных типов выглядит так:
T extends U ? X : Y
Берется некий тип
T
и присваивается типу U
(проверяется, входит ли T
в U
). Если да, возвращается X
, если нет - Y
(X
и Y
могут быть чем угодно, например, тем же исходным типом T
).Простейшая утилита
IsString
такого рода может выглядеть так:T extends string ? true : false
Она просто определяет, является ли переданный тип строкой.
Но можно делать и намного более сложные вещи.
Распределенные условные типы
Если передать в утилиту объединение типов, на выходе тоже можно получить объединение, потому что операция выполняется для каждого члена объединения - это называется _распределенные условные типы__ (distributed conditional type).
Но это работает только для "голых" типов, не обернутых в массивы/кортежи/промисы.
#typescript #ссылки #подкапотом
👍4
TypeScript. Пересечения
Статья (англ.): https://javascript.plainenglish.io/using-typescript-intersection-types-like-a-pro-a55da6a6a5f7
Статья подробно рассказывает об операторе
Если он работает с примитивными значениями, то понять, каким будет результат просто - этот оператор работает как логическое И:
Если один из операндов
Если один из операндов
Если же операнды являются объектами, то оператор работает с каждым полем этих объектов.
Если есть одинаковые поля с конфликтующими типами, будет
В статье есть интересный пример использования пересечения для функций с разной сигнатурой - фактически перегрузка функций с разными наборами параметров.
А в заключение дается пример использования пересечения вместе с MappedTypes, над которым можно немного поломать голову.
#typescript #ссылки #подкапотом
Статья (англ.): https://javascript.plainenglish.io/using-typescript-intersection-types-like-a-pro-a55da6a6a5f7
Статья подробно рассказывает об операторе
&
в TypeScript.Если он работает с примитивными значениями, то понять, каким будет результат просто - этот оператор работает как логическое И:
type T1 = 1 & number; // 1
type T2 = '1' & string; // '1'
type T3 = number & string; // never
Если один из операндов
never
, то результатом будет never
.Если один из операндов
any
, то результатом будет any
.type T4 = any & 1; // any
type T5 = any & boolean; // any
type T6 = any & never; // never
Если же операнды являются объектами, то оператор работает с каждым полем этих объектов.
interface Point {
x: number;
y: number;
}
interface Named {
name: string;
}
type NamedPoint = Point & Named;
// { x: number, y: number, name: string }
Если есть одинаковые поля с конфликтующими типами, будет
never
:interface A {
n: number
}
interface B {
n: string
}
type C = A & B; // { n: never }
В статье есть интересный пример использования пересечения для функций с разной сигнатурой - фактически перегрузка функций с разными наборами параметров.
А в заключение дается пример использования пересечения вместе с MappedTypes, над которым можно немного поломать голову.
#typescript #ссылки #подкапотом
👍3
Использование Typescript с React – руководство для новичков
Статья (рус.): https://habr.com/ru/company/otus/blog/456124/
Небольшое руководство для тех, кто только пытается совместить React и TypeScript в одном приложении. Рассказывает, где именно использовать типы в React.
1) Вместо PropTypes для пропсов компонента.
Тут же мы видим полезный тип
Если кроме указнных пропсов нужно принимать еще стандартные атрибуты HTML-элементов (`style`,
2) Для аргументов в обработчиках событий.
Еще полезный тип
3) Использование дженериков с компонентами
Компоненты React могут принимать обобщенные типы, которые затем могут использоваться для типизации, например, пропсов.
4) Хуки
Типизации требуют в основном два React-хука:
В статье есть пример типизации редуктора, он немного навороченный, но в целом понятный. Главное разобраться, как типизируются экшены с их полезной нагрузкой. Для этого создается отдельный сложный тип
5) typeof и keyof для типизирования компонентов с разными вариантами
Очень удобно, например, для кнопок, которые могут иметь разные стили. При этом набор возможных типов берется из ключей объекта.
#typescript
Статья (рус.): https://habr.com/ru/company/otus/blog/456124/
Небольшое руководство для тех, кто только пытается совместить React и TypeScript в одном приложении. Рассказывает, где именно использовать типы в React.
1) Вместо PropTypes для пропсов компонента.
export interface StandardComponentProps {
title?: string
children: React.ReactNode
}
export function StandardComponent({
children,
title = 'Default Title',
}: StandardComponentProps) {
}
Тут же мы видим полезный тип
ReactNode
.Если кроме указнных пропсов нужно принимать еще стандартные атрибуты HTML-элементов (`style`,
aria-hidden
, `className`), нужно просто расширить существующий встроенный интерфейс React.HTMLAttributes.2) Для аргументов в обработчиках событий.
function onFocus(e: React.FocusEvent) {
console.log('Focused!', e.currentTarget)
}
Еще полезный тип
FocusEvent
. Помимо него есть еще MouseEvent
и, вероятно, ряд других событий.3) Использование дженериков с компонентами
Компоненты React могут принимать обобщенные типы, которые затем могут использоваться для типизации, например, пропсов.
4) Хуки
Типизации требуют в основном два React-хука:
useRef
и useReducer
, остальные работают из коробки. Для этого тоже используются дженерики.В статье есть пример типизации редуктора, он немного навороченный, но в целом понятный. Главное разобраться, как типизируются экшены с их полезной нагрузкой. Для этого создается отдельный сложный тип
Action
, который использует условные типы и пересечения.5) typeof и keyof для типизирования компонентов с разными вариантами
Очень удобно, например, для кнопок, которые могут иметь разные стили. При этом набор возможных типов берется из ключей объекта.
const styles = {
primary: {
color: 'blue',
},
danger: {
color: 'red',
},
};
type StylesType = typeof styles;
export type ButtonType = keyof StylesType;
interface ButtonProps {
type: ButtonType
};
export function Button({ type = 'primary' }: ButtonProps) {
}
#typescript
Хабр
Использование Typescript с React – руководство для новичков
Друзья, в преддверии выходных хотим поделиться с вами еще одной интересной публикацией, которую хотим приурочить к запуску новой группы по курсу «Разработчик Jav...
👍3👎1
Изучаете ли вы код различных опенсорсных проектов (библиотек/инструментов)?
Anonymous Poll
13%
Да, часто это делаю
58%
Изредка
29%
Нет, не люблю разбираться в чужом коде
👍2
Typescript. Утилиты. Часть 4 (Uppercase, Lowercase, Capitalize, Uncapitalize)
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Третья часть (Parameters, ReturnType): https://yangx.top/react_junior/430
В этот раз 4 очень простые утилиты, которые имеют дело с регистром символов:
- Uppercase
- Lowercase
- Capitalize
- Uncapitalize
#typescript
Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Третья часть (Parameters, ReturnType): https://yangx.top/react_junior/430
В этот раз 4 очень простые утилиты, которые имеют дело с регистром символов:
- Uppercase
- Lowercase
- Capitalize
- Uncapitalize
#typescript
🔥2
TypeScript. Ключевое слово infer
Весь вечер пытаюсь разобраться с ключевым словом infer в TypeScript 🙂 Не сказать, что концепция самая очевидная, но вроде и не чрезмерно сложная, если я, конечно, все правильно понимаю.
Итак, infer может "выводить" один тип на основании другого. Использовать это ключевое слово можно только в условных конструкциях вместе с extend. Выведенный тип затем можно использовать, например, вернуть из условной конструкции.
Подробнее об условных типах: https://yangx.top/react_junior/431
Самый понятный для меня (но вероятно не самый популярный) пример использования infer - на приложенном скрине (взято со StackOverflow).
Утилита UnpackArrayType получает обобщенный тип T.
Затем ставится условие:
T extends (infer R)[]
Эта конструкция буквально означает, "можно ли представить T в виде массива элементов какого-нибудь типа R". При этом тип R буквально "выводится" из типа T с помощью infer. Если T равно number[], то R будет равно number.
Если условие получилось выполнить, возвращается свежевыведенный тип R.
Неплохой разбор infer есть в статье Understanding infer in TypeScript (англ.)
Там автор начинает с более простых концепций: типа never, оператора extends, объединений, а затем переходит к работе с функциями и собственно ключевому слову infer.
К слову, именно infer лежит в основе работы утилиты ReturnType.
В конце статьи приводяется некоторые популярные кейсы использования infer, например, выведение возвращаемого типа из промиса.
#ссылки #typescript #подкапотом #infer
Весь вечер пытаюсь разобраться с ключевым словом infer в TypeScript 🙂 Не сказать, что концепция самая очевидная, но вроде и не чрезмерно сложная, если я, конечно, все правильно понимаю.
Итак, infer может "выводить" один тип на основании другого. Использовать это ключевое слово можно только в условных конструкциях вместе с extend. Выведенный тип затем можно использовать, например, вернуть из условной конструкции.
Подробнее об условных типах: https://yangx.top/react_junior/431
Самый понятный для меня (но вероятно не самый популярный) пример использования infer - на приложенном скрине (взято со StackOverflow).
Утилита UnpackArrayType получает обобщенный тип T.
Затем ставится условие:
T extends (infer R)[]
Эта конструкция буквально означает, "можно ли представить T в виде массива элементов какого-нибудь типа R". При этом тип R буквально "выводится" из типа T с помощью infer. Если T равно number[], то R будет равно number.
Если условие получилось выполнить, возвращается свежевыведенный тип R.
Неплохой разбор infer есть в статье Understanding infer in TypeScript (англ.)
Там автор начинает с более простых концепций: типа never, оператора extends, объединений, а затем переходит к работе с функциями и собственно ключевому слову infer.
К слову, именно infer лежит в основе работы утилиты ReturnType.
В конце статьи приводяется некоторые популярные кейсы использования infer, например, выведение возвращаемого типа из промиса.
#ссылки #typescript #подкапотом #infer
👍5
Forwarded from Cat in Web
Создание модальных окон в React: от основ до продвинутого уровня
Статья (англ.): https://medium.com/tinyso/how-to-create-a-modal-component-in-react-from-basic-to-advanced-a3357a2a716a
Статья пошагово описывает процесс создания React-компонента модального окна: от разметки до поведения.
Для управления видимостью используется проп
Обрабатывается закрытие при клике на кнопку Close, подложку, а также по нажатию клавиши Escape.
Текст заголовка и содержимое модального окна передаются динамически через пропсы (`title` и `children`).
Появление и исчезновение модального окна сопровождается анимацией с использованием компонента
И наконец, модальное окно рендерится вне контейнера с помощью портала (`ReactDOM.createPortal`).
#react #interface
Статья (англ.): https://medium.com/tinyso/how-to-create-a-modal-component-in-react-from-basic-to-advanced-a3357a2a716a
Статья пошагово описывает процесс создания React-компонента модального окна: от разметки до поведения.
Для управления видимостью используется проп
show
. Кроме того компонент отслеживает свое закрытие и вызывает функцию onClose
.Обрабатывается закрытие при клике на кнопку Close, подложку, а также по нажатию клавиши Escape.
Текст заголовка и содержимое модального окна передаются динамически через пропсы (`title` и `children`).
Появление и исчезновение модального окна сопровождается анимацией с использованием компонента
CSSTransition
из пакета react-transition-group (в этот пакет вынесена вся transition-функциональность React).И наконец, модальное окно рендерится вне контейнера с помощью портала (`ReactDOM.createPortal`).
#react #interface
Medium
How to create a Modal Component in React from basic to advanced?
If you are a frontend developer, I think you know that modal is really ubiquitous UI elements on the web. Today I will show you how to…
👍4🔥1