我正在尝试使用带给定Object类型的流的函数来键入一个函数,该函数接受一个对象,其中每个属性均由创建值的“ create”函数代替。我希望能够使用键入到$ElementType
的{{1}}映射值类型,但是它似乎没有正确地关联键和值。
这是一个简化的示例:
$Keys
但是,流报告每种类型与相反键的值不兼容。例如。 // @flow
type TestType = {
foo: number,
bar: string,
}
declare function create<
K: $Keys<TestType>,
V: $ElementType<TestType, K>,
O: {[K]: () => V}
>(obj: O): TestType
const tmp = create({
foo: () => 5,
bar: () => 'whatever',
})
的值与foo
的值不兼容:
bar
实时示例:Try Flow REPL
答案 0 :(得分:1)
这两个属性 foo
/ bar
中的一个可以传递给 function <的obj
param / em> 创建。您不能将它们放在一起,因为您有UnionType
。
K: $Keys<TestType>, // UNION: number | string
V: $ElementType<TestType, K>, // UNION: foo | bar
O: {[K]: () => V} // UNION: foo: () => number | bar: () => string
这有效:
type TestType = {
foo: number,
bar: string,
}
declare function create<
K: $Keys<TestType>,
V: $ElementType<TestType, K>,
O: {[K]: () => V}
>(obj: O): TestType
const foo = create({ foo: () => 5 })
const bar = create({ bar: () => 'whatever' })
答案 1 :(得分:1)
我认为流程$ObjMap
example非常接近您想要的。它基本上是开箱即用的(将run
重命名为create
):
// let's write a function type that takes a `() => V` and returns a `V` (its return type)
type ExtractReturnType = <V>(() => V) => V;
declare function create<O: {[key: string]: Function}>(o: O): $ObjMap<O, ExtractReturnType>;
const o = {
foo: () => 0,
bar: () => 'foo',
baz: () => true,
};
type TestType = {
foo: number,
bar: string,
baz: number, // Error since true is not a number
}
const p: TestType = create(o);