У меня небольшие проблемы flowtype ing это правильно. В основном я передаю объект аргументов, в котором я внутренне проверяю, были ли переданы необходимые аргументы. Проблема в том, что я не уверен, как вывести это для потока. может потребоваться в различных комбинациях.
// @flow
export const PATHS = {
reports: {
required: ['businessId']
// $ExpectError
get: ({ businessId }) => `business/${businessId}/reports`
},
// ... etc, leaving out the rest for sake of example simplicity
}
и, наконец, внутри моей функции
// @flow
import * as R from 'ramda'
const getDownloadUrl = (path: $Keys<typeof PATHS>, params: DownloadUrlParams) => {
const pathArgs = R.pick(PATHS[path].required, params)
// ^ gets .required object properties, basically { ...[required] } = object
const hasAllArgs = (paramsObj: DownloadUrlParams) => R.toPairs(paramsObj)
.every((entry) => {
// R.toPairs === Object.entries
if (!entry[1]) {
throw Error(`Fetch type: ${path}. Missing required param ${entry[0]}`)
}
return !!entry[1]
}
hasAllArgs(pathArgs)
return PATHS[path].get(pathArgs)
}
Дело в том, что я знаю, что предоставленные аргументы действительны, потому что функция hasAllArgs()
выдает ошибка в противном случае, мне просто нужно как-то передать эту информацию в тип потока
Я попытался принудительно применить приведение типа для объекта, который я передаю:
type PickedObject = {|
[$Keys<DownloadUrlParams>]: $Values<DownloadUrlParams>
|}
type EnforceTypeFunction = <V>(value: V) => $NonMaybeType<V>
type RequiredArgs = $ObjMap<PickedObject, EnforceTypeFunction>
const pathArgs: RequiredArgs = { ...R.pick(PATHS[path].required, params) }
Это отчасти работает и, по-видимому, является шагом в правильном направлении, проблема в том, что теперь сам параметр относится к одному из этих двух типов, а не к точному типу для каждого параметра
basically i need to somehow enforce instead of
[key: string]: Date | string
до
[key: string]: <exact type of that key's value>