Typescript - 对象的 Curried 函数参数 属性

Typescript - Curried Function Argument For Object Property

我正在尝试预设一个作为参数传递给函数的对象的 属性。这样我就不必设置这个特定的 属性 因为它已经在我稍后调用这个函数时提供了。

用例是为 api 调用设置版本。

withApiVersion

const API_VERSION = "1";

const addApiVersion = <T>(obj: T) => ({ ...obj, version: API_VERSION });

export const withApiVersion = <Fn extends (arg: any) => any>(fn: Fn) => <Arg>(
  arg: Arg
): ReturnType<Fn> => fn(addApiVersion(arg));

示例api方法

export const getCertificates = ({
  version,
  searchString,
  skip,
  take = 50
}: {
  version: string;
  searchString?: string;
  skip?: number;
  take?: number;
}) => Promise.resolve([{ id: 1 }]);
const result = withApiVersion(getCertificates);

一切正常,除了在函数参数的“部分应用”之后我无法获得正确的类型 -> 理想情况下 withApiVersion 将 return 一个需要参数的函数version 属性 缺失。

提前感谢任何帮助或小费!

您可以使用OmitArg中取出一些道具。另外 Arg 应该在第一个函数上推断出来,因为它来自函数。您不需要捕获函数的实际类型,您对结果和参数感兴趣,因此将它们用作您的类型参数:

export const withApiVersion = <Arg extends { version: string }, Result>(fn: (arg: Arg | (Omit<Arg, "version"> & { version: string; })) => Result) => (
  arg: Omit<Arg, 'version'>
): Result => fn(addApiVersion(arg));

Playground Link

Arg(Omit<Arg, "version"> & { version: string; }) 应该解析为相同的东西,但是由于 Omit 中的条件类型,打字稿无法解决这个问题。为了在我们的函数体中不需要任何断言,我们在一个联合中使用了两个等价的类型。这将允许他的实现使用 (Omit<Arg, "version"> & { version: string; }) 成分作为函数的参数,而在调用站点,两者应该解析为相同的类型并且不会导致任何问题。