Источник: Nuances of Programming
Курс SkillFactory Frontend-разработчик PRO. Получите перспективную творческую профессию. Изучите JavaScript и TypeScript. Выполните 13 проектов в портфолио.
Утилиты — это функции, используемые для выполнения определенных задач в программном приложении. Они гибкие, легко поддерживаются и могут использоваться многократно. В этой статье будет представлен набор утилит, необходимых для повышения эффективности приложения 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 вручную и снижает вероятность ошибок во время выполнения, вызванных неправильным парсингом.
- Предоставляет значение по умолчанию, возвращаемое при неудачном парсинге, поэтому является полезным инструментом для обработки граничных случаев в приложении.
Заключение
Используя эти утилиты, вы сможете сосредоточиться на написании основной функциональности. Все остальное предоставьте им.
Читайте также:
Перевод статьи Radovan Stevanovic: Supercharge Your Typescript React Application with These Essential Utilities