Утилиты — это функции, используемые для выполнения определенных задач в программном приложении. Они гибкие, легко поддерживаются и могут использоваться многократно. В этой статье будет представлен набор утилит, необходимых для повышения эффективности приложения React на TypeScript.
Эти утилиты облегчают выполнение общих задач, улучшают читаемость кода и делают его более удобным для сопровождения.
isEnum
export const isEnum = <T, R>(e: T, value: R): boolean =>
Object.values(e).includes(value);
Функция isEnum
принимает два аргумента: value
и enumeration
. Аргумент value
— это значение, наличие которого в перечислении нужно проверить. Аргумент enumeration
— это объект, содержащий набор значений, которые считаются допустимыми.
Функция возвращает булево значение, указывающее, существует ли value
в enumeration
. Использование защиты типа с помощью value is keyof typeof enumeration
гарантирует сужение типа value
до значения, которое существует в перечислении.
Вот пример того, как можно использовать утилиту isEnum
в коде:
enum UserRole {
ADMIN = 'ADMIN',
USER = 'USER',
}
const userRole = UserRole.ADMIN;
console.log(isEnum(UserRole, userRole)); // true
В этом примере утилита isEnum
используется для проверки принадлежности userRole
к типу-перечислению UserRole
. Функция возвращает true
, указывая на то, что userRole
является членом типа-перечисления UserRole
.
Утилита isEnum
— это простой, но мощный инструмент, который поможет писать более эффективный и надежный код, снизить частоту ручных проверок и повысить читабельность.
extractQueryParams
Функция extractQueryParams
— помощник в извлечении параметров запроса из строки поиска. Эта функция принимает два параметра: строку поиска и флаг dry
. При значении true флаг dry
не будет преобразовывать типы извлекаемых параметров запроса. Функция возвращает объект с извлеченными параметрами запроса.
Ниже приведен код функции extractQueryParams
:
export const extractQueryParams = <T>(search: string, dry = false): T => {
if (!search) return {} as T;
return search
.replace("?", "")
.split("&")
.reduce((data: T, item) => {
const [k, v] = item.split("=");
if (!k || !v) return data;
if (dry) return { ...data, [k]: v };
if (v.includes(",")) return { ...data, [k]: v.split(",") };
if (["true", "false"].includes(v)) return { ...data, [k]: v === "true" };
if (v === "null") return { ...data, [k]: null };
if (!Number.isNaN(+v)) return { ...data, [k]: +v };
return { ...data, [k]: v };
}, {} as T);
};
Функция extractQueryParams
может пригодиться при работе с параметрами запроса в URL. Она принимает строку поиска, которая обычно является частью URL после символа ?
, и возвращает объект с извлеченными параметрами запроса. Это значительно упрощает доступ к параметрам запроса в коде, позволяя использовать ключи возвращаемого объекта для доступа к значениям.
extractQueryParams
также поддерживает преобразование значений параметров запроса в различные типы данных, такие как массивы, булевы значения, числа и null. Это полезно при работе с параметрами запроса, представляющими различные типы данных.
Вот пример использования утилиты extractQueryParams
:
const search = '?code=12345&name=John&active=true';
const queryParams = extractQueryParams<{ code: number, name: string, active: boolean }>(search);
console.log(queryParams);
// Вывод: { code: 12345, name: 'John', active: true }
Как видите, эта утилита позволяет извлекать параметры запроса из строки поиска и преобразовывать их в типизированный объект. В данном примере параметр code
преобразуется в число, name
— в строку, а active
— в булево значение.
Можно также использовать параметр dry
для возврата параметров запроса без преобразования типов:
const search = '?code=12345&name=John&active=true';
const queryParams = extractQueryParams<{ code: string, name: string, active: string }>(search, true);
console.log(queryParams);
// Вывод: { code: '12345', name: 'John', active: 'true' }
Эта утилита экономит много времени и усилий при парсинге параметров запроса, обеспечивая более надежный и безопасный для типов метод.
delay
Следующей утилитой в нашем наборе является функция delay
. Она принимает время задержки в миллисекундах и возвращает промис, который разрешается через определенное время.
Вот реализация функции delay
:
export const delay = (delayTime = 300): Promise<void> =>
new Promise((resolve) => setTimeout(resolve, delayTime));
А вот пример того, как можно использовать функцию delay
:
async function delayedAction() {
console.log("Taking action!");
await delay(500);
console.log("Action taken!");
}
Вот какие преимущества дает функция delay
.
- Помогает сохранить чистоту и читабельность кода: вместо того чтобы устанавливать вызов
setTimeout
и управлять обратным вызовом, можно вызвать функциюdelay
и передать желаемое время задержки. Это облегчает понимание того, что происходит в коде, особенно для тех, кто его читает. - Позволяет сделать код более гибким и пригодным для повторного использования: вместо того чтобы писать вызовы
setTimeout
по всему коду, можно импортировать функциюdelay
и применять ее везде, где нужно задержать выполнение какого-либо кода. Это упрощает управление задержками в приложении и сокращает объем кода, который необходимо написать.
В целом, функция delay
— это простой, но мощный инструмент, помогающий писать более качественный и удобный в сопровождении код.
cb
cb
— утилита, которая позволяет разработчикам передавать обратные вызовы ленивым способом. Она представляет собой функцию высшего порядка, которая принимает fn
обратного вызова и его аргументы и возвращает новую функцию, которая может быть вызвана позже для выполнения первоначального обратного вызова, обеспечивая при этом безопасность типов и сохраняя читабельность кода.
Реализация функции cb
выглядит следующим образом:
export const cb = <T extends any[], V>(fn: (...args: T) => V, ...args: T): (() => V) => {
return () => fn(...args);
};
Вот пример использования функции cb
:
<button onClick={cb(toggle, !isActive)}>Toggle</button>
Вот какие преимущества дает функция cb
.
- Позволяет легко отложить выполнение функции до тех пор, пока она не понадобится, что может повысить производительность приложения.
- Делает код более читабельным, упрощает детали выполнения обратного вызова и позволяет сфокусироваться на логике приложения.
formatCurrency
Следующая утилита в нашей коллекции — formatCurrency
. Эта утилита используется для преобразования чисел в формат валюты, в частности долларов США. Функция принимает два параметра: value
и replaceDoubleZero
. value
— это число, которое необходимо отформатировать как валюту, а replaceDoubleZero
— булево значение, которое определяет, нужно ли удалять “.00” в конце строки валюты.
Вот реализация formatCurrency
:
export function formatCurrency(value: number, replaceDoubleZero?: boolean) {
const formattedValue = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(value);
if (replaceDoubleZero) {
return formattedValue.replace(".00", "");
}
return formattedValue;
}
А вот пример использования formatCurrency
:
const value = 123456;
const formattedValue = formatCurrency(value, true);
console.log(formattedValue); // "$123,456"
Вот какие преимущества дает formatCurrency
.
- С помощью этой утилиты можно легко форматировать числа в виде валюты, не прибегая к написанию сложного кода и не заботясь о локалях и символах валют.
- Применение параметра
replaceDoubleZero
позволяет удалить “.00” из конца строки валюты, что может быть полезно в некоторых сценариях.
В целом, это простой и мощный инструмент для форматирования чисел в виде валюты.
capitalize
Утилита capitalize
— инструмент для преобразования строк. Она принимает строку и вовзвращает новую с заглавной первой буквой.
Реализация:
export const capitalize = (str: string): string => {
if (str.length === 0) {
return str;
}
return str[0].toUpperCase() + str.slice(1);
};
Вот пример использования утилиты capitalize
в React-приложении:
const name = "john doe";
const capitalizedName = capitalize(name);
console.log(capitalizedName); // "John Doe"
Вот какие преимущества дает утилита capitalize
.
- Обеспечивает чистый и лаконичный способ форматирования строк, делая код более читабельным и удобным для сопровождения.
- Избавляет от необходимости писать свою реализацию капитализации строк, освобождая время и ресурсы для решения других задач.
Независимо от того, работаете ли вы над небольшим проектом или крупным корпоративным приложением, утилита capitalize
станет ценным инструментом в вашем арсенале.
onChange и распаковка
Следующая утилита, которую мы рассмотрим, — onChange
. Эта функция высшего порядка принимает обработчик события и возвращает новый обработчик события, который автоматически распаковывает значение события изменения. Утилита onChange
особенно полезна при работе с React-формами.
Реализация функции onChange
:
import { ChangeEvent } from 'react';
type E = ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>;
export const unpackE = (e: E): string => {
return e.target.value;
};
export const onChange = (handler: (v: string) => void) => (e: E) =>
handler(unpackE(e));
Рассмотрим пример использования onChange
в React-компоненте:
import React, { useState } from 'react';
import { onChange } from './utils';
const ExampleForm = () => {
const [value, setValue] = useState('');
return (
<input
type="text"
value={value}
onChange={onChange(setValue)}
/>
);
};
В этом примере утилита onChange
обрабатывает изменения в элементе input
. Когда значение input
изменяется, функция onChange
вызывает функцию setValue
с обновленным значением. Утилита onChange
упрощает процесс распаковки значения из события изменения, что облегчает написание чистого и лаконичного кода.
Вот какие преимущества дает onChange
.
- Облегчает написание чистого и лаконичного кода.
- Избавляет от необходимости писать повторяющийся код для распаковки значения из события изменения.
- Упрощает управление событиями изменений в React-компоненте, поскольку утилиту
onChange
можно повторно использовать в нескольких компонентах.
toHumanReadable
Утилита toHumanReadable
используется для преобразования строк в формате snake_case и camelCase в формат, удобный для человека. Реализация довольно проста.
- Сначала все символы
_
заменяются пробелами. - Затем символы нижнего регистра, за которыми следует верхний регистр, заменяются строчной буквой, за которой следует пробел и заглавная буква.
- Потом строка преобразуется в нижний регистр, и первый символ каждого слова пишется с заглавной буквы.
Вот реализация функции toHumanReadable
:
export const toHumanReadable = (str: string) => {
return str
.replace(/_/g, " ")
.replace(/([a-z])([A-Z])/g, "$1 $2")
.toLowerCase()
.replace(/(^|\s)\S/g, function (t) {
return t.toUpperCase();
});
};
Рассмотрим пример использования toHumanReadable
:
import { toHumanReadable } from './utils';
const snake_case = 'snake_case';
const humanReadable = toHumanReadable(snake_case);
console.log(humanReadable); // Snake Case
parse
Утилита parse
используется для парсинга строкового представления объекта JSON в строго типизированный объект. Функция принимает два аргумента: value
— строковое представление объекта JSON; def
— значение по умолчанию, возвращаемое в случае неудачи.
export const parse = <T>(value: string | undefined, def: T): T => {
if (!value) return def;
try {
return JSON.parse(value) as T;
} catch (e) {
return def;
}
};
Пример:
const jsonString = '{"name": "John Doe", "age": 30}';
const parsedValue = parse<{name: string, age: number}>(jsonString, {name: '', age: 0});
console.log(parsedValue); // {name: 'John Doe', age: 30}
Утилита parse
предоставляет удобный и надежный способ парсинга строкового представления объекта JSON в строго типизированный объект. Вот какие преимущества дает parse
.
- Позволяет избежать парсинга строки JSON вручную и снижает вероятность ошибок во время выполнения, вызванных неправильным парсингом.
- Предоставляет значение по умолчанию, возвращаемое при неудачном парсинге, поэтому является полезным инструментом для обработки граничных случаев в приложении.
Заключение
Используя эти утилиты, вы сможете сосредоточиться на написании основной функциональности. Все остальное предоставьте им.
Читайте также:
- Как оптимизировать настройку приложений React Native
- Шаблон “Декоратор” в разработке на TypeScript
- Next.js и React.js: что выбрать для проекта
Читайте нас в Telegram, VK и Дзен
Перевод статьи Radovan Stevanovic: Supercharge Your Typescript React Application with These Essential Utilities