2016-12-15 3 views
1

Я сейчас в процессе сравнения Google Closure Compiler и статический тип проверки Flow с точки зрения выразительности. Одна вещь, которую я знаю, как делать в Closure, но не в Flow, представляет собой набор именованных объектов, все из которых имеют один и тот же тип. В закрытии для этого можно использовать the @enum annotation.Объект с тем же типом для всех клавиш в потоке

/** @enum {function(number):number} */ 
const unaryFunctions = { 
    sin: Math.sin, 
    cos: Math.cos, 
    square: function(x) { return x*x; }, 
}; 

Есть ли способ сделать что-то подобное с помощью Flow? Думаю, я мог бы использовать словарь ES6 вместо простого объекта, но при перекрестном компиляции в ES5 это приносило бы значительные накладные расходы. Я думаю, что такие конструкции кажутся довольно идиоматичными, поэтому я удивлен, что в документах я не смог найти подходящее описание типов.

ответ

1

Вы можете сделать это следующим образом:

const unaryFunctions: { ['sin'|'cos'|'square']: (number) => number } = { 
    sin: Math.sin, 
    cos: Math.cos, 
    square: function(x) { return x*x; }, 
}; 

Если вы не хотите, чтобы дублировать ключи, вы можете переписать его немного:

const unaryFunctions_ = { 
    sin: Math.sin, 
    cos: Math.cos, 
    square: function(x) { return x*x; }, 
}; 

const unaryFunctions: { [$Keys<typeof unaryFunctions_>]: (number) => number } = unaryFunctions_; 
+0

Спасибо! Можете ли вы добавить ссылки на документы? Я нашел ['$ Keys'] (https://flowtype.org/docs/utility-types.html#keyst), но не нашел документацию для того, как вы используете' [...] '. С другой стороны, я нашел [свойства индексатора] (https://flowtype.org/docs/syntax.html#object-types), которые должны разрешать 'const unaryFunctions: {[name: string]: (number) => number } = {...} 'если я правильно понимаю. Не ограничивает конечный набор ключей, поэтому это не совсем '@ enum', но я знаю еще одну ситуацию, когда мне будет нужно что-то вроде этого. Или ваш '[...]' экземпляр этого как-то? – MvG

+0

https://flowtype.org/docs/objects.html#objects-as-maps Вы указываете тип ключа внутри скобок. Это может быть строка или что-то более конкретное – vkurchatkin

+2

В новых версиях Flow вы можете пропустить имя в indexer, поэтому вместо '{[name: string]: string}' вы можете просто написать '{[string]: string}' – vkurchatkin

Смежные вопросы