在Flow中声明一个通用形状的对象

问题描述 投票:3回答:1

考虑一个功能:

const f = k => v => array =>
  array.reduce(
    (total, current) => ({
      ...total,
      [current[k]]: current[v]
    }),
    {}
  );

此函数接受键k,值v,然后输入一个对象数组作为输入,并返回一个类似于地图的对象,其中键和值取自键k和值v的值。例如,

const k = 'key';
const v = 'value';
const input = [{ key: 1, value: 100 }, { key: 2, value: 200 }, { key: 3, value: 300 }];

f(k)(v)(input); // -> { '1': 100, '2': 200, '3': 300 }

我正在努力在数组中声明对象类型。它们必须具有两个属性,但这些属性不是静态的。不过,它们可以来自k之前的varrayarray中的每个物体都应该具有类似的形状

const k = 'key';
const v = 'value';
{ [k]: 123, [v]: 456 }; // -> { 'key': 123, 'value': 456 }

到目前为止,我正是在这一点上:

const f = <K>(k: K) => <V>(v: V) => (array: Array<{ [k]: K, [v]: V }>) =>
  array.reduce(
    (total, current) => ({
      ...total,
      [current[k]]: current[v]
    }),
    {}
  );

这是技术上有效的Flow语法,但是给了我一个错误:

1: const f = <K>(k: K) => <V>(v: V) => (array: Array<{ [k]: K, [v]: V }>) =>
                                                        ^ Cannot use `K` as a type because `K` is a value. To get the type of a value use `typeof`

如何声明一个类型,该类型是从先前声明的泛型类型派生的形状对象?这在Flow中可行吗?

javascript flowtype static-typing
1个回答
0
投票

Flow中的{ [...]: ... }语法与ES6中的语法并不相同。 { [k]: K, [v]: V }并不意味着该对象必须具有k类型的密钥Kv类型的密钥V。相反,语法用于表示indexer property in Flow。因此,{ [k]: K, [v]: V }无效,因为您只能指定一个索引器属性。但是,让我们说我们只有{ [k]: K }。这仍然无法按预期工作,因为这将表示“具有类型为k的值的K类型的键的对象”。

不幸的是,我不认为Flow目前支持你想要做的事情。我相信这种类型将属于dependent types,目前Flow不支持,因为数组的类型取决于kv的值。

© www.soinside.com 2019 - 2024. All rights reserved.