ReturnType<T>
提取函数的返回类型。
是否有一种方法可以定义ArgumentsType<T>
并以tuple
格式提取函数的参数类型?
例如,
ArgumentsType<(a: number, b: string) => boolean>
将是[number, string]
。
答案 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
传递它,就像我得到它一样。