【问题标题】:Typescript - add one argument to a function's params打字稿 - 向函数的参数添加一个参数
【发布时间】:2020-02-20 15:47:21
【问题描述】:
type SomeFunc = (a:string, b:number, c:someCustomType) => number;

我想创建一个和上面一样的类型,除了最后添加了一个参数。比方说,d:number;

type SomeFuncAltered = (a:string, b:number, c:someCustomType, d:number) => number;

虽然我不想手动制作整个类型,但我很确定这里可以使用 Parameters<func> 的巧妙技巧。

【问题讨论】:

  • 如果它被添加在前面,你可以这样做:type Alter<T extends (...args: any) => any> = (extraArg: number, ...args: Parameters<T>) => ReturnType<T>;。我不知道如何在最后添加它,因为 rest args 只能在最后。
  • 前面很简单 :) 但结尾不是

标签: typescript


【解决方案1】:

这是可能的,但非常复杂。更多信息可以在@jcalz - Push type to the end of the tuple with skipping optional 的这个答案中找到。

在您的情况下,我们可以重用上述答案中的一些实用程序,确切地说是ConsPush,并通过使用它们来制作您需要AddArgument 的最终类型。考虑:

type SomeFunc = (a: string, b: number, c: string) => number;

// some utility types for working with tuples
type Cons<H, T extends readonly any[]> =
    ((head: H, ...tail: T) => void) extends ((...cons: infer R) => void) ? R : never;

type Push<T extends readonly any[], V>
    = T extends any ? Cons<void, T> extends infer U ?
    { [K in keyof U]: K extends keyof T ? T[K] : V } : never : never;

// final type you need
type AddArgument<F, Arg> = 
F extends ((...args: infer PrevArgs) => infer R) 
? (...args: Push<PrevArgs, Arg>) => R : never

// function type with added boolean argument at the end
type NewFunction = AddArgument<SomeFunc, boolean>

【讨论】:

  • 那是……史诗。
【解决方案2】:

由于这里接受的答案似乎对我不起作用(使用 TS 4),我编写了自己的类型,可以在函数末尾添加任意数量的参数。

type AddParameters<
  TFunction extends (...args: any) => any,
  TParameters extends [...args: any]
> = (
  ...args: [...Parameters<TFunction>, ...TParameters]
) => ReturnType<TFunction>;

用法:

type SomeFunc = (a: string, b: number, c: someCustomType) => number;
type SomeFuncAltered = AddParameters<SomeFunc, [d: number]>;
// SomeFuncAltered = (a:string, b:number, c:someCustomType, d:number) => number;

注意:此解决方案还允许您添加命名参数。

【讨论】:

    【解决方案3】:

    您可以为基函数 args 使用其他类型:

    type FuncBaseArgs = {
      a: string;
      b: number;
      c: boolean;
    }
    
    type SomeFunc = ({...obj }: FuncBaseArgs) => number;
    
    type SomeFuncAltered = ({...obj }: FuncBaseArgs, d: number) => number;
    

    【讨论】:

    • 不错。不是通用的,但非常实用。
    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多