Учетная запись экстремиста TypeScript

Всем привет, так приятно видеть, что загадочные заголовки все еще вызывают интерес😉

Сегодня размышлял на тему фильтрации. И, отчасти к своему собственному удивлению, я обнаружил, что эта тема гораздо менее прямолинейна, чем я когда-то думал.

Я хочу представить вам три способа фильтрации массива в TypeScript:

  • Пыльный, старый, скучный, нечитаемый способ, безопасный для типов
  • Блестящий современный, удобочитаемый способ, который является домом для личинки
  • Причудливый, странный, получитаемый способ, который смешивает оба и является типобезопасным.

Пыльный, старый, скучный, нечитаемый

const values = [4, "ho", 7, "hi"];

// Try filtering imperatively
const imperativeNumbers: number[] = [];
for (const val in values) {
    if (typeof val === "string") {
        imperativeNumbers.push(val); // Error! Nice! Bug caught!
    }
}

// try again
for (const val in values) {
    if (typeof val === "number") {
        imperativeNumbers.push(val); // swell
    }
}

Итак, ребята, вы знаете это со старых времен или с тех пор, когда вы были еще новичком в JS/TS. Он очень прост в написании кода, делает то, что должен, и даже совершенно безопасен для типов!

Но нам это не нравится, потому что требуется много времени, чтобы заглянуть в этот цикл и понять, что он просто что-то фильтрует. И это не неизменно. Это как раз 2008 год.

Зачем нам беспокоиться, если мы можем просто делать это больше

Блестящий, современный, читабельный

const values = [4, "ho", 7, "hi"];

// Try filtering declaratively
const declarativeNumbers = values.filter(val => typeof val === "string");

Ааааа, разве это не красота? Одна строчка и мы знаем, что происходит😍.

За исключением того, что это полный помет крупного рогатого скота!

Посмотрите на это в своей IDE или на Игровой площадке, и вы увидите, что тип declarativeNumbers совершенно бесполезен, а значение просто неверно.

Почему? Что ж, если я правильно понял цифры, Array.prototype.filter старше, чем весь язык TypeScript! И хотя идея использования подхода, основанного на предикатах, для фильтрации чего-либо действительно хороша, инструментам чертовски сложно с ней справиться!

Так что, на самом деле, TypeScript в настоящее время даже не пытается.

Конечно, есть типичная охрана, в которую вы попали после того, как с ума сходили по этому поводу 💣🤬😭🤯 в течение месяца или около того, но, честно говоря, с самого начала это казалось подозрительным, верно?

const values = [4, "ho", 7, "hi"];

 // Type is narrowed
const bug = values.filter((val): val is number => typeof val === "string");

// Type is correctly narrowed
const maggot = values.filter((val): val is number => typeof val === "number"); 

Признай это, чувак, это просто скрытое утверждение. Что делает его личинкой, даже при правильном использовании. Это еще не ошибка, но я уже вижу, что когда-нибудь она будет!

Но, может быть, между этими двумя подходами есть золотая середина? Что-нибудь

Причудливый, странный, получитаемый

Вы, вероятно, думаете что-то вроде «Дорогой бог программирования, пожалуйста, не заставляйте меня возвращаться к циклам for только потому, что эта приманка только что попалась мне на глаза» прямо сейчас. Не так ли?

Что ж, вот одна модель, которая, если она будет широко распространена, могла бы исправить некоторые из наших страданий:

const values = [4, "ho", 7, "hi"];

const safeButStrangeNumbersWrong = values.flatMap(val => typeof val === "string" ? val : []);
const safeButStrangeNubersRight = values.flatMap(val => typeof val === "number" ? val : []);

"Детская площадка"

Здесь нет никаких утверждений, это однострочник, и он работает. Но никто не поймет, на кой черт мы это делаем.

Сделай еще, вставь ссылку на эту статью в комментарий😉

Правда, правда?

Я имею в виду, действительно действительно?

Это полностью зависит от качества кода и безопасности рефакторинга, к которым вы стремитесь в своем проекте. И стоимость времени выполнения, с которой вы можете мириться. Согласно моим (простым) тестам, Array.filter действительно эффективен по сравнению как с императивным стилем, так и с причудливым обходным путем. flatMaping работает хуже, хотя и не совсем ужасно.

Посмотрите мой полный пример всех подходов на Площадке!

А теперь хлопайте, ребята! О, и подпишитесь, распечатайте мое фото, повесьте над кроватью и молитесь мне 2 раза в день о благополучии ТС…

Должен просто любить социальные сети

Быстрый вопрос для раздела комментариев: поможет ли SEO, если я добавлю нерелевантные слова, которые обычно встречаются во вступлении, в конец статьи? Нравиться:

Почему функция фильтра в TypeScript не сужает тип? Почему мой тип неверен после применения функции фильтра массива? Как сделать тип фильтра массива безопасным? Это лучший способ отфильтровать массив в TypeScript. Горячие цыпочки. Лучший способ фильтрации массива в 2023 году. ChatGPT ненавидит этот трюк. Как успешно пройти собеседование на веб-разработчика, зная безумные мелочи о фильтрации в TypeScript. Даже у старших веб-разработчиков возникают проблемы с правильной фильтрацией в TypeScript. Слишком много статей в Интернете содержат нерелевантный контент — мне нужен фильтр. Получайте удовольствие от фильтрации массивов!