Typescript中是否有类似ReturnType <t>的ArgumentsType <t>?

时间:2018-07-12 07:22:45

标签: typescript

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

是否有一种方法可以定义ArgumentsType<T>并以tuple格式提取函数的参数类型?

例如,

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

7 个答案:

答案 0 :(得分:11)

修改

自从编写原始答案以来,打字稿现在具有内置类型(在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)?]

编辑:TypeScript 3.0已发布,以下代码可以正常工作。

在当前版本的打字稿(2.9)中,如果不拼写所有参数,则无法做到这一点。在接下来几天将发布的下一版本的打字稿(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

答案 1 :(得分:2)

从TypeScript 3.1开始,Parameters类型现已成为标准库的一部分。

type Result = Parameters<(a: number, b: string) => boolean>; // [number, string]

答案 2 :(得分:1)

目前尚无法为任何可能的函数提取类型的参数。但是您可以尝试执行以下操作:

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

请注意,此选项不使用任何可选参数-它们只是从输出中省略。我暂时无法找到抓住它们的方法。

答案 3 :(得分:0)

我创建了这样的常见辅助类型的集合:https://github.com/joonhocho/tsdef

在这里您可以找到许多打字稿的帮助器模式。 您也可以通过npm或yarn进行安装。 npm i -D tsdef

答案 4 :(得分:0)

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

例如我想要以下内容,以便如果authService.login签名发生更改,我不必修改代理-只需调用它即可。

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

使用Parameters<T>,您可以执行以下操作

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

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

我花了两次努力才发现,在两次出现的...上都需要params

答案 5 :(得分:0)

@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];

  // ...
}

答案 6 :(得分:0)

对于我的问题,我使用了以下样式:

const myFunction = <T>(items: T[], config: FuseConfigType) => {
  const fuse = new Fuse(items, config);

  return (pattern: string): T[] =>
    pattern === '' ? items : fuse.search(pattern).map(({ item }) => item);
};

export default fuseSearch;

我得到 T 类型,items 中每个项目的类型,然后当我想返回函数时,我使用 T 传递它,就像我得到它一样。