TypeScript或FlowType中的正确对函数?

时间:2018-01-25 04:14:02

标签: typescript types flowtype

我已经根据我对TypeScript的了解编写了对函数的以下实现:

const pairs = <A, B extends keyof A>(a: A): [keyof A, A[B]][] => {
  const mapper = (k: keyof A): [keyof A, A[B]] => [k, a[k]]
  return Object.keys(a).map(mapper)
}

问题在于它不保留有效的组合,例如:

const myPairs = pairs({ a: 1, b: false, c: "a" })

返回类型:

type MyPairs = Array<["a" | "b" | "c", string | number | boolean]>

虽然实际上是正确的:

type MyPairs = Array<["a", number] | ["b", boolean] | ["c", string]>

因此,我可以做出令人讨厌的事情:

myPairs.push(["a", "BUG"]) // This type checks

如何在TypeScript或FlowType中编写pairs版本以产生所需的返回类型?

- 编辑

以下是目前提议的解决方案在我的编辑器中不起作用的图片。

enter image description here

1 个答案:

答案 0 :(得分:1)

假设您想要此返回类型:

type MyPairs = Array<['a', number] | ['b', boolean] | ['c', string]>

你可以为它制作一个映射类型:

type Pairs<T> = Array<{
    [P in keyof T]: [P, T[P]]
}[keyof T]>

并按照以下方式实施您的方法:

const pairs = <A extends Record<string, any>>(a: A): Pairs<A> => {
    return Object.keys(a).map((k) => [k, a[k]]) as any;
}
如果你的目标是ES6,那么

甚至更简单:

const pairs = <A>(a: A): Pairs<A> => {
    return Object.entries(a) as any;
}

<强> Working Playground