Как правильно определить типы для действий Redux?

У меня есть приложение, использующее Redux для управления состоянием, и я пытаюсь добавить аннотации типа Flow.

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

Я создал тип union Action, а затем в функции редуктора я использую switch для принятия решений о том, какое состояние возвращать, на основе свойства type действия. В каждом случае оператора switch я обращаюсь к разным свойствам моего параметра action.

Я не понимаю, почему Flow сообщает мне, что не может найти определенные свойства аргумента action. Кажется, все определено правильно, и я действительно не вижу здесь ничего неправильного.

Вот мой тестовый пример:

https://flowtype.org/try/#0C4TwDgpgBAggxsAlgewHZQLxQFBSgHygG8pRIAuKAcgDEBJAJQGUAVKgGigBMBDYHygHkARgCsICKAF9cBYqXARKVJgFEAwoIByAEQ5REwCAFs6XSgGdgAJ0SoA5tOzYy0JvyOZisgDaIrlDDW1jwgADwi4ggAfOzYMtgAZgCuqAgo6NYQXMlwEAAUVnxKUO7FnDzpaIFVqACUlKjJxsIQ1t54FgDuhnAAFlD5lUhoAHSudR14UHA8FtC0jKxUlESy01BZwMnW6EVGo35Wo4l2XHSoXBAAHvmGJpjRBkbGo4hcmBhYwxmjvPxvLh1ADc6ycG1m82oak0uhWUw2Wx2ew8EEO-mAJzOFyut3uxkezxMgM+31qbxeZhBYJkGyuiR4yR8wHIYLwSN2UAADKC8DIpEA

Я подумал, что возможно проблема была связана с использованием инструкции switch, поэтому вот версия с использованием if с теми же проблемами:

https://flowtype.org/try/#0C4TwDgpgBAggxsAlgewHZQLxQFBSgHygG8pRIAuKAcgDEBJAJQGUAVKgGigBMBDYHygHkARgCsICKAF9cBYqXARKVJgFEAwoIByAEQ5REwCAFs6XSgGdgAJ0SoA5tOzYy0JvyOZisgDaIrlDDW1jwgADwi4ggAfOzYMtgAZgCuqAgo6NYQXMlwEAAUVnxKUO7FnDzpaIFVqACUlKjJxsIQ1t54iIlQ+ZVIaAB0rpgYWLSMrFR1HXhQWcDJ1uhFRgN+VgOJdlx0qFwQAB75hiaY0QZGxgOIXCNYfRkDvPzXXHUA3LIyeLJdPQ+DYajMZqTS6KYzPDzRbLDwQNb+YCbba7fZHE7GM4XEyvO5QAGoa6XMwfL6yWTQpZQAAMnykQA


person Brian McAllister    schedule 12.10.2016    source источник
comment
Не зная, что делает поток, ваши редукторы выглядят нормально, если это действительно то, что действие должно отправлять. Использует ли поток как-то здесь избыточность или вы просто тестируете то, что, по вашему мнению, делает избыточность?   -  person ajmajmajma    schedule 12.10.2016
comment
Эти две вещи разные, я просто пытаюсь добавить аннотации типа Flow к своим действиям Redux и редьюсерам.   -  person Brian McAllister    schedule 12.10.2016
comment
Понятно. Не уверен, что вы имеете в виду под последним редактированием - почему вы ожидаете, что это будет ошибка?   -  person ajmajmajma    schedule 12.10.2016
comment
Э, да, ты прав, это не будет ошибкой, я ошибся. Я удалю это.   -  person Brian McAllister    schedule 12.10.2016


Ответы (1)


Прежде всего, обратите внимание, что ваша функция reduce не является допустимым редьюсером. Редуктор избыточности должен иметь следующую подпись

(state: State, action: Action) => State

Flow пессимистично относится к уточнениям (теоретически вы можете изменить ссылку action.data в обратном вызове). Способ помочь Flow сохранить уточнение — использовать константную привязку (документы)

function reduce(state: State, action: Action): number {
  switch (action.type) {
    case 'FIRST': 
      const data = action.data;
      return state.list.findIndex(item => item.id === data.id);
    case 'SECOND': 
      const itemId = action.itemId
      return state.list.findIndex(item => item.id === itemId);
    default:
      return 0;
  }
}

или, IMO, еще лучше, разделить случаи на несколько вспомогательных функций

function findIndex(state: State, id): number {
  return state.list.findIndex(item => item.id === id);
}

function reduce(state: State, action: Action): number {
  switch (action.type) {
    case 'FIRST': 
      return findIndex(state, action.data.id)
    case 'SECOND': 
      return findIndex(state, action.itemId)
    default:
      return 0;
  }
}

Кроме того, вы можете найти пример приложения потокового типа в репозитории Redux (см. examples/todos-flow).

person gcanti    schedule 12.10.2016
comment
Как использовать константы вместо строк? Это глупо - person Daryn K.; 29.10.2018