Фильтрация ложных значений при получении реального результирующего типа с помощью TypeScript.

Как вы знаете, в JavaScript есть 6 значений falsy: null | undefined | false | 0 | ‘’ | NaN. Вероятно, вы также знаете, как удалить значения falsy из массива в JavaScript с помощью функции Array.filter():

arr.filter(elem => !!elem);

Мы можем сделать его даже короче:

arr.filter(Boolean);

Проблема: опыт разработчиков

Это работает во время выполнения, как и ожидалось. Однако при работе с TypeScript мы не получаем ожидаемого типа после фильтрации значений falsy. Мы знаем, что массив не содержит ложных значений, но для TypeScript результирующий массив теоретически может их содержать. По сути, TypeScript не может сузить тип результирующего массива:

filteredNumbers на самом деле не содержит значения falsy, но результирующий тип остается тем же. Это не большая проблема, но это не идеальный DX, потому что мы должны использовать необязательную цепочку повсюду или, что еще хуже, ненулевой оператор.

Решение

Улучшить это оказывается довольно просто. Мы можем использовать некоторые типы утилит TypeScript для достижения того, что мы хотим:

Если мы вызовем sift(), передав определенный выше массив numbers, TypeScript сообщит нам, что это просто тип number!

Обратите внимание: если вы не хотите определять эту функцию самостоятельно, вы можете просто установить radash и использовать метод массива sift(). Radash — это своего рода более компактный и современный lodash с безопасным типом.

Ресурсы

Радаш: https://radash-docs.vercel.app/docs/getting-started

Метод sift(): https://radash-docs.vercel.app/docs/array/sift