Я только начал внедрять проверку типов с помощью Facebook Flow в одном из моих проектов и столкнулся с некоторыми проблемами. Я пытаюсь сделать следующее с картой:
/* @flow */ let testMap: Map<string, Array<number>> = new Map(); let key: string = "testString"; if (!testMap.has(key)) { testMap.set(key, []) } testMap.get(key).push(1);
Но я получаю сообщение об ошибке:
Cannot call `testMap.get(...).push` because property `push` is missing in undefined [1]
Пример Se в потоке try: https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVMCmAXM3MDO2AsgIYAOAXGGeQDxEBOAlgHYDmANGAIKOOkAnnVYBXALYAjTIwB8ssAF4wrTEloAKAJQBuDDjABrTIOpM27JWABE+IgGVsLDtb2pmUMBoCEdkhQA6AAtSAg1jQS0tMABvVDA8Qn9yAIIccJNuAG0AXS1UAF90P1oA9nSIrQDyUQIgjQBGXVQgA
Это, конечно, потому что функция get в интерфейсе Map определяется как:
get(key: K): V | void;
Но я ожидал, что Flow узнает, что ключ на самом деле устанавливается чуть выше.
Есть ли какие-либо предложения о том, как мне изменить свой код, чтобы сделать Flow счастливым?
Большое спасибо!
Как вы упомянули, проблема в том, что ваш звонок на Map.get может вернуть void, как вы можете видеть в V | void.
Map.get
void
V | void
Flow не имеет возможности узнать, был ли определен ваш ключ или нет, так как он может измениться во время выполнения.
Таким образом, вам нужно проверить, не является ли возвращенное значение undefined, прежде чем обращаться к его push методу.
undefined
push
const arr = testMap.get(key); if (arr) { arr.push(1) } else { // map "testMap" didn't contain a value for key "key" }
полная демонстрация в потоке repl: https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVMCmAXM3MDO2AsgIYAOAXGGeQDxEBOAlgHYDmANGAIKOOkAnnVYBXALYAjTIwB8ssAF4wrTEloAKAJQBuDDjABrTIOpM27JWABE+IgGVsLDtb2pmUMBoCEdkhQA6AAtSAg1jQS0tMABvVDA8Qn9yAIIccJNuAG0AXS1UAF90AGM4ViIwUn4rP1oA9nSI3XQPLyrGaLiE9oDyUQIgjQBGfIKwTBg02PiwYGAwcQobWoprMAATZnXWAHJcUtZsUjZKsAA3UhhRTDAoOEYjExsI60KgA
Другой подход был бы таким:
let arr = testMap.get(key); if (!arr) { arr = []; testMap.set(key, arr); } arr.push(1);