Проблема
Основная проблема - подпись .filter()
. Он будет всегда возвращать массив того же типа, с которого вы начали. Компилятор TypeScript не может гарантировать что-либо еще. Вот пример:
const arr/*: (string | number) */ = ["one", 2, 3, "four", 5, 6];
const numbers/*: number[]*/ = arr.filter(x => typeof x === "number");
console.log(numbers);
Ссылка на игровую площадку
Этот работает , если вы не учитываете типы, но он функционально эквивалентен следующему:
const arr/*: (string | number)[]*/ = ["one", 2, 3, "four", 5, 6];
const numbers/*: number[]*/ = arr.filter(x => x !== "one");
console.log(numbers);
Playground Link
В обоих случаях у вас есть массив смешанных типов и некоторая функция фильтрации. Чтобы гарантировать, что результатом будет только определенный c тип, вам необходимо изучить код и сделать выводы. Однако компилятор работает не так - вызов .filter()
на Array<T | U>
может снова дать только Array<T | U>
, общий c не изменился.
Решение
Что можно сделать, это изменить порядок ваших .map
и .filter
. Вам нужно будет их переписать, но с точки зрения типов он будет работать правильно. Я также сделал logi c более связным - прямо сейчас вы double фильтруете неявно. map()
преобразует только некоторые типы, но не другие, таким образом выполняя косвенный фильтр. Фактический вызов .filter()
затем отсеивает несопоставленные / мягко отфильтрованные значения.
Правильный logi c и правильное сохранение типа, таким образом, будут следующими:
const Ids: number[] = Object.values(submit()!)
.filter(formfield => formfield.value === 'true')
.map(formfield => Number(formfield.id))
Ссылка на игровую площадку
Это более короткая и правильная форма логики c, которую вы хотите.
- Реальное условие фильтрации
formfield.value === 'true'
извлекается само в .filter()
вызов. .filter()
запускает первый , поэтому вы гарантированно получите одинаковые типы с точки зрения компилятора и , список которых вы только что уменьшили только для тех элементов, которые вас интересуют. .map()
не выполняет в точности то, для чего предназначено - отображение 1: 1 для каждого значения массива. Не нужно делать никаких лог c более сложных. Таким образом, ему не нужно беспокоиться о том, что правильно, а что нет, чтобы выполнить преобразование.