Typescript - 从参数元组中删除最后一个元素,柯里化最后一个参数

Jør*_*edt 7 typescript

我想用打字稿进行柯里化并且有:


const findValueInDb = (value: number, dbSpec: string) => `found it, it's here: ${dbSpec}!`

const createFindValue = (dbSpec: string) =>
    (...params: Omit<Parameters<typeof findValueInDb>, "1">) => findValueInDb(...params, dbSpec)

const theResult = createFindValue("theDb")(10)
Run Code Online (Sandbox Code Playgroud)

这是行不通的,如果在源函数中添加参数的话,也不会很灵活。如何定义柯里化合约?删除最后一个参数但保留其他参数的一个?

Min*_*uel 10

在 TypeScript 4 中,您可以使用推断的元组类型来获取除最后一个(或第一个等)之外的所有元素:

type Head<T extends any[]> = T extends [ ...infer Head, any ] ? Head : any[];
Run Code Online (Sandbox Code Playgroud)
const findValueInDb = (value: number, dbSpec: string) => `found it, it's here: ${dbSpec}!`

const createFindValue = (dbSpec: string) =>
    (...params: Head<Parameters<typeof findValueInDb>>) => findValueInDb(...params, dbSpec)

const findValue = createFindValue("theDb")(10)
Run Code Online (Sandbox Code Playgroud)

游乐场链接

  • 这是一个很棒的解决方案 - 它甚至保留了参数名称,而其他方法可能不会。就我而言,我需要删除调用签名中的最后一个参数,这优雅地解决了问题:`type RemoveLastParameter&lt;T extends (...args: any) =&gt; any&gt; = (...args: Head&lt;参数&lt;T&gt;&gt;) =&gt; ReturnType&lt;T&gt;;` (3认同)
  • 这非常好,我还构建了一个 Tail 类型,用于删除第一个参数。这可以与“扩展”类型结合使用:`(...args: [string, ...Tail&lt;Params&lt;typeof func&gt;&gt;]) =&gt; void`。这将显式地重新输入第一个参数。然而,这将失去参数名称,而尾/头本身则不会。 (2认同)
  • @mfulton26 将“Head”中的“T extends”更改为“Required&lt;T&gt; extends”。问题是,使用可选参数,这意味着数组(在本例中)可能有 1 或 2 个条目长,因此推理失败 (2认同)