Javascript 流类型-将函数的对象映射到函数结果

Javascript 流类型-将函数的对象映射到函数结果,javascript,flowtype,Javascript,Flowtype,我试图用flow类型一个函数,给定一个对象类型,它接受一个对象,其中每个属性都被一个创建值的“create”函数替换。我希望能够使用键入的$ElementType将值类型映射到$Keys,但它似乎没有正确关联键和值 下面是一个简化的示例: // @flow type TestType = { foo: number, bar: string, } declare function create< K: $Keys<TestType>, V: $Element

我试图用flow类型一个函数,给定一个对象类型,它接受一个对象,其中每个属性都被一个创建值的“create”函数替换。我希望能够使用键入的
$ElementType
将值类型映射到
$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
可以传递给函数
obj
参数create。您无法将它们放在一起,因为您有
UnionType

K: $Keys<TestType>, // UNION: number | string
V: $ElementType<TestType, K>, // UNION: foo | bar
O: {[K]: () => V} // UNION: foo: () => number | bar: () => string
K:$Keys,//UNION:number | string
V:$ElementType,//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' })
type TestType={
傅:号码,
酒吧:字符串,
}
声明函数创建<
K:$钥匙,
V:$ElementType,
O:{[K]:()=>V}
>(obj:O):TestType
const foo=create({foo:()=>5})
const bar=create({bar:()=>'whatever'})
我认为流程与您想要的非常接近。它基本上是开箱即用的(将
run
重命名为
create
):

//让我们编写一个函数类型,它接受一个“()=>V”,并返回一个“V”(其返回类型)
类型ExtractReturnType=(()=>V)=>V;
声明函数create(o:o):$ObjMap;
常数o={
foo:()=>0,
条:()=>“foo”,
baz:()=>对,
};
类型TestType={
傅:号码,
酒吧:字符串,
baz:number,//错误,因为true不是数字
}
常数p:TestType=create(o);

啊,是的,这正是我想要的。谢谢我可以提出一个后续问题,除非这很简单,但是我知道如何让o的值任意地允许值或函数吗?e、 g.
const o={foo:()=>5,bar:'barrrr'}
试试这个。我不相信它是完全安全的,但它似乎在很大程度上是有效的()到目前为止,我还没有找到任何不安全的方法。比我想象的要简单。谢谢
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' })
// 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);