У меня есть код, который получает объект, выполняет итерацию его ключей и выполняет различные действия в зависимости от наличия конкретного ключа в другом объекте конфигурации.
Вот абстрактный пример:
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
?
Есть ли способ исправить ошибки, изменив аннотации типов без изменения кода?
попробуй ответить для stackoverflow.com/questions/37897927/… странно но там помогло
@JuanMendes, я не знаю. Просто написал механически. Ваш вариант действительно более читабельный и предпочтительный, но это не решает проблемы.
Вот почему это комментарий, я действительно не думал, что это исправит. Хотя кажется, что в конечном итоге может быть добавлена более простая проверка, такая как in
.
@skyboyer большое спасибо за ссылку на этот вопрос! Это действительно странно, но ошибки исчезли после того, как я добавил определение типа в параметр key
в функции обратного вызова.
Поток верен в том, что ваш объект типа 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'))]);
просто для информации: кажется, что поток не понимает
hasOwnProperty
в аналогичном случае, поэтому это означает, что он также не понимаетindexOf(key) !== -1
. Статья Уточнения типов docs тоже не помогла :(