Руководство по использованию ts-reset для TypeScript
Типизация в JavaScript всегда была проблемой для разработчиков. Из-за динамической типизации разработчикам, пришедшим из языков с сильной типизацией, таких как C# или Java, сложно приспособиться к использованию JavaScript. TypeScript был создан для решения этой проблемы, но некоторые желаемые функции всё ещё отсутствуют.
Один из примеров — функция JSON.parse()
. TypeScript считает, что результат этой функции имеет тип any
, что создаёт ряд проблем, поскольку создаёт ложное впечатление, что с предоставленным ответом можно работать. Это может привести к возникновению ошибок. Более ожидаемым подходом было бы возвращать тип unknown
, заставляя разработчика проводить дополнительную проверку.
Представляем ts-reset, кнопку сброса для TypeScript, призванную улучшить типы для распространённых JS API. В этом руководстве мы рассмотрим, как использовать и настраивать ts-reset для приложений TypeScript.
Что такое ts-reset
ts-reset — пакет с открытым исходным кодом, предоставляющий набор правил, изменяющих встроенные в TypeScript типы. ts-reset помогает улучшить типизацию TypeScript и сделать её более соответствующей ожиданиям пользователей. Он также делает код более читабельным и удобным для поддержки и позволяет избежать ошибок, вызванных ошибками типов. Этот пакет можно рассматривать как TypeScript-версию css-reset, представляющую собой список правил, сбрасывающих все стили браузера по умолчанию и устраняющих потенциальные несоответствия между различными браузерами.
Зачем нужен ts-reset
Типы по умолчанию в TypeScript для некоторых встроенных функций не самые удачные. Далее приведены два примера, в которых стандартные типы TypeScript приводят к трудноуловимым багам:
.json
(вfetch
) иJSON.parse
возвращают типany
..filter(Boolean)
выдаёт ложные значения
Использование ts-reset помогает решить эти проблемы, делая типизацию ожидаемой:
.json
(вfetch
) иJSON.parse
возвращают типunknown
..filter(Boolean)
ведёт себя так как вы ожидаете
Более подробно мы рассмотрим это в следующем разделе. А пока давайте посмотрим, как установить пакет в проект.
Настройка ts-reset в проекте
Начать работу с ts-reset
очень просто. Первый шаг — установка проекта:
npm i -D @total-typescript/ts-reset
Затем создайте файл reset.d.ts
в проекте со следующим кодом:
// Не добавляйте в этот файл ни каких других строк кода!
import "@total-typescript/ts-reset";
Теперь вы готовы приступить к работе! Если не нужно глобальное использование и вы предпочитаете включать его только в файл или даже в отдельную функцию, можете использовать inline подход. Для этого просто добавьте нужный хелпер в начало файла:
// Делает возвращаемый тип JSON.parse unknown
import "@total-typescript/ts-reset/json-parse";
//теперь применяется ts-reset
const result = JSON.parse("{}"); // unknown
N.B. Чтобы импорты работали, нужно убедиться, что модуль установлен на NodeNext
или Node16
в tsconfig.json
.
Примеры использования ts-reset
Теперь рассмотрим примеры использования пакета ts-reset для решения перечисленных ранее проблем.
Заставляем JSON.parse
возвращать unknown
До ts-reset JSON.parse
возвращал значение any
. Это может привести к неприятным, трудноуловимым багам, потому что они отключают проверку типов значений, которые описывают:
// До ts-reset
const result = JSON.parse({}); // any
С ts-reset возвращаемый тип JSON.parse
меняется на unknown
. Теперь нужно либо проверить unknown
, чтобы убедиться, что это правильный тип, либо преобразовать его с помощью as
:
// После ts-reset
const result = JSON.parse("{}"); // unknown
Делаем, чтобы .json()
возвращал unknown
Точно так же, как JSON.parse()
, .json()
, возвращает тип any
, вводя нежелательный тип any
в код приложения, что также может привести к неприятным багам:
// До ts-reset
fetch("/")
.then((res) => res.json())
.then((json) => {
console.log(json); // any
});
Заставляя res.json
возвращать тип unknown
, мы осознаём необходимость проверки результатов fetch
, поскольку теперь мы не доверяем результату метода res.json()
:
// ts-reset
fetch("/")
.then((res) => res.json())
.then((json) => {
console.log(json); // unknown
});
Делаем, чтобы .filter(Boolean)
фильтровал ложные значения
Поведение .filter
по умолчанию ведёт себя не так, как ожидается. Учитывая набор значений в массиве со значением undefined
, применение конструктора Boolean
в качестве метода фильтрации удаляет все ложные значения в массиве, оставляя только не ложные значения. Однако TypeScript по-прежнему воспринимает типы как (number | undefined)[]
, используя исходные значения массива, а не результат новой фильтрации массива.
Для примера возьмём следующий код:
// ДО ts-reset
const filteredArray = [1, 2, undefined].filter(Boolean); // (number | undefined)[]
После применения ts-reset метод filter
стал вести себя так, как и ожидается. Он действует как предикат типа на переданный массив и удаляет все ложные значения из членов массива:
// После ts-reset
import "@total-typescript/ts-reset/filter-boolean";
const filteredArray = [1, 2, undefined].filter(Boolean); // number[]
Будущие проблемы с совместимостью
Поскольку пакет ts-reset не требует настройки со стороны пользователя, у него нет проблем с совместимостью. Обратите внимание, что ts-reset предназначен для использования в коде приложения, а не в коде библиотеки. Это связано с тем, что каждое включаемое правило, будет вносить изменения в глобальную область, а это означает, что пользователи, импортирующие библиотеку, будут неосознанно использовать ts-reset.
Заключение
ts-reset — отличный пакет утилит, помогающий решить проблемы с типами в JavaScript. В этой статье мы узнали, как использовать ts-reset для улучшения типизации в TypeScript по умолчанию, чтобы сделать её более предсказуемой и защищённой от ошибок. ts-reset помогает типам TypeScript вести себя в коде так, как ожидается. Надеюсь, вы получите удовольствие от использования ts-reset для создания отличных проектов на TypeScript!