Ошибка типа потока при попытке получить значение объекта с помощью динамического ключа

У меня есть код, который получает объект, выполняет итерацию его ключей и выполняет различные действия в зависимости от наличия конкретного ключа в другом объекте конфигурации.

Вот абстрактный пример:

type InputObject = {
  foo: number,
  bar: number,
  baz: number,
};

const multipliers = {
  bar: 3,
};

function processData(data: InputObject) {
  Object.keys(data).forEach(key => {
    const value = data[key];

    if (Object.keys(multipliers).indexOf(key) !== -1) {
      console.info(value * multipliers[key]);
    } else {
      console.info(value);
    }
  });
}

Если я проверю этот код с помощью команды flow check, он выдаст следующие ошибки:

Cannot get multipliers[key] because:
• property baz is missing in object literal [1].
• property foo is missing in object literal [1].

Почему Flow не понимает, что multipliers[key] выполняется, только если key существует в multipliers? Есть ли способ исправить ошибки, изменив аннотации типов без изменения кода?

просто для информации: кажется, что поток не понимает hasOwnPropertyв аналогичном случае, поэтому это означает, что он также не понимает indexOf(key) !== -1. Статья Уточнения типов docs тоже не помогла :(

skyboyer 26.09.2018 21:35

попробуй ответить для stackoverflow.com/questions/37897927/… странно но там помогло

skyboyer 26.09.2018 21:39

@JuanMendes, я не знаю. Просто написал механически. Ваш вариант действительно более читабельный и предпочтительный, но это не решает проблемы.

Oleksandr Kovpashko 26.09.2018 21:41

Вот почему это комментарий, я действительно не думал, что это исправит. Хотя кажется, что в конечном итоге может быть добавлена ​​более простая проверка, такая как in.

Juan Mendes 26.09.2018 21:45

@skyboyer большое спасибо за ссылку на этот вопрос! Это действительно странно, но ошибки исчезли после того, как я добавил определение типа в параметр key в функции обратного вызова.

Oleksandr Kovpashko 26.09.2018 21:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
5
527
1

Ответы 1

Поток верен в том, что ваш объект типа InputObject имеет три обязательных поля, а множители имеют только одну панель полей. Ключ относится к ключу типа InputObject. Один из способов - преобразовать ключ в новую строку и использовать ее как ссылку для поиска. Однако из-за этого поток теряет ссылку на тип ключа, поэтому $Keys<InputObject> имеет смысл обеспечить более строгую типизацию.

type InputObject = {
  foo: number,
  bar: number,
  baz: number
}

const multipliers = {
  bar: 3,
}

function processData(data: inputObject) {
  Object.keys(data).forEach(key: $Keys<InputObject> => {
    const value = data[key];
    const lookupKey = String(key);
    if (multipliers.hasOwnProperty(lookupKey)) {
      console.info(value * multipliers[lookupKey]);
    else {
      console.info(value);
    }
});
const lookupKey = String(key); - эта линия творит настоящую магию // Error ({foo:3}[('bar')]) // Magic ({foo:3}[(String('bar'))]);
Buggy 10.10.2018 20:40

Другие вопросы по теме