代码之家  ›  专栏  ›  技术社区  ›  Joon

typescript中是否存在类似returntype<t>的参数类型?

  •  8
  • Joon  · 技术社区  · 6 年前

    ReturnType<T> 提取函数的返回类型。

    有没有办法定义 ArgumentsType<T> 在中提取函数的参数类型 tuple 格式?

    例如,

    ArgumentsType<(a: number, b: string) => boolean> [number, string] 是的。

    4 回复  |  直到 6 年前
        1
  •  16
  •   Titian Cernicova-Dragomir    5 年前

    编辑

    自编写原始答案以来,typescript现在有了一个内置类型(在 lib.d.ts )获取调用的参数类型 Parameters

    type argsEmpty = Parameters<() => void> // []
    type args = Parameters<(x: number, y: string, z: boolean) => void> // [number, string, boolean]
    type argsOpt = Parameters<(x: number, y?: string, z?: boolean) => void> // [number, (string | undefined)?, (boolean | undefined)?]
    

    编辑 TypeScript3.0已被释放以下代码按预期工作。

    在当前版本的typescript(2.9)中,如果不拼写出所有参数,这是不可能的。在接下来几天发布的Typescript(3.0)的下一个版本中,它将成为可能:

    type ArgumentsType<T> = T extends  (...args: infer U) => any ? U: never;
    
    type argsEmpty = ArgumentsType<() => void> // []
    type args = ArgumentsType<(x: number, y: string, z: boolean) => void> // [number, string, boolean]
    type argsOpt = ArgumentsType<(x: number, y?: string, z?: boolean) => void> // [number, (string | undefined)?, (boolean | undefined)?]
    

    如果你安装 npm install typescript@next 你已经可以玩这个了,这个月的某个时候应该可以用。

    注意

    我们还可以使用此新功能将元组扩展为参数:

    type Spread<T extends any[]> = (...args: T)=> void;
    type Func = Spread<args> //(x: number, y: string, z: boolean) => void
    

    您可以阅读有关此功能的更多信息 here

        2
  •  2
  •   Karol Majewski    5 年前

    从类型脚本3.1开始, Parameters 类型现在是标准库的一部分。

    type Result = Parameters<(a: number, b: string) => boolean>; // [number, string]
    
        3
  •  1
  •   Cerberus    6 年前

    目前还没有办法提取这两种类型 任何函数可能的参数量。但你可以试试这样的方法:

    type ArgumentTypes<T> = T extends () => any ? never[] :
                            T extends (a1: infer T1) => any ? [T1] :
                            T extends (a1: infer T1, a2: infer T2) => any ? [T1, T2] :
                            // continue here for any reasonable number of args
                            never;
    

    按以下步骤检查:

    const args0: ArgumentTypes<() => boolean> = []; // correct
    const args1: ArgumentTypes<(a: number) => boolean> = [1]; // correct
    const args2: ArgumentTypes<(a: number, b: string) => boolean> = [1, 'str']; // correct
    
    const oops0null: ArgumentTypes<() => boolean> = null; // error, arguments are array (but empty one)
    const oops01: ArgumentTypes<() => boolean> = [1]; // error, arguments must be empty
    
    const oops10: ArgumentTypes<(a: number) => boolean> = []; // error, we need one argument
    const oops12: ArgumentTypes<(a: number) => boolean> = [1, 2]; // error, we need only one argument
    const oops1wrong: ArgumentTypes<(a: number) => boolean> = ['str']; // error, argument must be number
    
    const oops21: ArgumentTypes<(a: number, b: string) => boolean> = [1]; // error, we need two arguments
    const oops23: ArgumentTypes<(a: number, b: string) => boolean> = [1, 'str', undefined]; // error, we need only two arguments
    const oops2wrong: ArgumentTypes<(a: number, b: string) => boolean> = ['str', 1]; // error, arguments are reversed
    

    请注意,这没有使用任何可选参数-它们只是从输出中省略。我现在没办法抓住他们。

        4
  •  0
  •   Joon    5 年前

    我创建了一个常见帮助器类型的集合,如下所示: https://github.com/joonhocho/tsdef

    这里有很多类型脚本的帮助模式。 您也可以通过npm或yarn安装。 npm i -D tsdef

        5
  •  0
  •   Simon_Weaver    5 年前

    我肯定有很多用途 Parameters<T> 但我想用一种方法在一个私有成员身上为同一方法提供代理方法,这似乎是一种完美的方法。

    我想要以下的,这样如果 authService.login 签名更改我不需要修改我的代理-无论是什么调用它。

    login(username: string, password: string) { this.authService.login(username, password); }
    

    参数<t> 你可以这样做

    login = (...params: Parameters<AuthService['login']>) => this.authService.login(...params);
    

    当然,这样做的好处是,如果您有复杂的参数,它只会很好地处理自己(可能不建议只使用两个字符串!)

    我花了几次努力才发现我需要 ... 两次出现时 params 是的。

        6
  •  0
  •   Tom    5 年前

    扩展 @Titian Cernicova-Dragomir's answer ,如果使用的是命名函数表达式,因此无法定义类型,则可以使用 typeof 就像这样:

    function updateTable<T extends IHasOBJECT_ID>(
      diff: Diff,
      cache: { [id: string]: Table<T, Array<keyof T>> & IHasOBJECT_ID & IHasCONFLICTS & IHasOPTIONS },
    ) {
      // Use typeof to get the parameter type for cache
      const cacheItem: Parameters<typeof updateTable>[1] = cache[diff.id];
    
      // ...
    }