如何使用扩展运算符调用重载函数

how to call an overloaded function with the spread operator

我想使用扩展运算符从 fp-ts 调用 pipe function,但它没有为此重载。

相反,我不得不将 pipe 转换为 any,这看起来很难看并且会损害可读性。

我可以扩充现有类型吗?

我创建了这个简单的示例,这里是 codesandbox。现实世界的例子使我无法确切知道我将传递给管道的参数数量。

import { pipe } from "fp-ts/function";

const o = { a: "a", b: "b", c: "c" };

type O = typeof o;
type G = (o: O) => O;

const set = (...getters: G[]) => {
  /*
  Expected 1-20 arguments, but got 0 or more.ts(2556)
  function.d.ts(225, 33): An argument for 'a' was not
  */
  return pipe(...getters);
  // this works but is ugly
  // return (pipe as any)(...getters);
};

const getters: G[] = [
  (o: O) => ({ ...o, a: "5" }),
  (o: O) => ({ ...o, b: "6" }),
  (o: O) => ({ ...o, c: "8" })
];

set(...getters);

你能试试下面的方法吗?

const getters = [
  (o: O) => ({ ...o, a: "5" }),
  (o: O) => ({ ...o, b: "6" }),
  (o: O) => ({ ...o, c: "8" })
] as const;

const lotsOfO = pipe(o, ...getters);

getters 必须是常量,以便 typescript 推断出正确的重载形式,即在这种情况下的参数数量。

我认为这是幺半群的工作。


import { foldMap } from "fp-ts/Array";
import { getEndomorphismMonoid } from "fp-ts/lib/Monoid";
import { identity, pipe } from "fp-ts/lib/function";

const o = { a: "a", b: "b", c: "c" };

type O = typeof o;
type G = (o: O) => O;

const monoid = getEndomorphismMonoid<O>();

const set = (getters: G[]) => pipe(getters, foldMap(monoid)(identity));

const getters: G[] = [
  (o: O) => ({ ...o, a: "5" }),
  (o: O) => ({ ...o, b: "6" }),
  (o: O) => ({ ...o, c: "8" }),
];

console.log(set(getters)(o));


不知道大家是否熟悉Monoid,一个monoid就是typeclass有两个函数。 concatempty concat 是获取两个值并将其连接在一起的函数,而 empty 是当您的类型没有任何值时它将获得空值。

例如 monoid for sum 是这样的

const monoidSum: Monoid<number> = {
  concat: (x, y) => x + y,
  empty: 0
}

您可以在数组的 foldMap 上使用此 monoidSum 并获得整数列表的总和。

这里我们使用了一个名为getEndomorphismMonoid的函数,这是一个内置于fp-ts中的函数。 Endmorphism 表示一个函数接受一个参数作为输入并且 return 相同类型。

export interface Endomorphism<A> {
  (a: A): A
}

对于 concat,它将两个函数连接在一起,对于空的,它使用 identity 函数。