typescript - 从泛型函数创建泛型类型
问题描述
我试图声明一个基于另一种泛型类型的泛型类型,但没有成功。
目标是编写我自己的测试框架并根据另一个(方法)键入一些参数。
type Arguments<T> = T extends (...args: infer U) => any ? U : never;
// my custom test method
const methodCall = <T extends (...args: any) => any>(args: {
method: T;
response: ReturnType<T>;
myArguments: Arguments<T>;
}): boolean => {
const { method, myArguments, response } = args;
return method.apply(null, myArguments) === response;
};
const test1 = (toto: string) => {
return toto === "success";
};
// usage of my custom function
methodCall({
method: test1,
myArguments: ["fail"],
response: false
});
// this is what I want to type
interface MyHelpers {
methodCall: any // HOW TO TYPE THIS?
methodCall2: (args: { flag: boolean }) => boolean;
}
// I would expose only the helpers object
const helpers = (): MyHelpers = {
methodCall: <T extends (...args: any) => any>(args: {
method: T;
response: ReturnType<T>;
myArguments: Arguments<T>;
}): boolean => {
const { method, myArguments, response } = args;
return method.apply(null, myArguments) === response;
},
methodCall2: (args: { flag: boolean }): boolean => {
return args.flag;
}
};
我期待另一个调用助手的对象能够helpers().methodCall(...)
像在助手中声明的那样被键入。不与any
.
操场可以在这里找到。
谢谢!
解决方案
如果我理解正确的话,你已经很接近了。您可以在函数语法(定义签名的地方,methodCall
就像定义函数实现一样)和属性语法(定义methodCall
为恰好是 lambda 的属性,这与您拥有它的方式接近)之间进行选择。
如果使用函数语法,则在尖括号 ( <>
) 中定义泛型、括号之间的参数列表以及冒号后的返回类型;就好像您正在定义一个没有主体的函数。如果使用属性语法,则定义一个 lambda,尖括号中的泛型、括号之间的参数列表以及粗箭头 ( =>
)后面的返回类型;您正在使用该名称定义属性并输入您的类型—<a href="https://www.typescriptlang.org/docs/handbook/functions.html#writing-the-function-type" rel="nofollow noreferrer ">一种函数类型——在冒号之后。无论哪种方式都适合你。
(我还从您的自定义Arguments
实用程序类型切换到未记录的Parameters
内置.)
interface MyHelpers {
methodCall<T extends (...args: any) => any>(args: {
method: T;
response: ReturnType<T>;
myArguments: Parameters<T>;
}): boolean;
methodCall2: (args: { flag: boolean }) => boolean;
}
interface MyHelpersWithObjectSyntax {
methodCall: <T extends (...args: any) => any>(args: {
method: T;
response: ReturnType<T>;
myArguments: Parameters<T>;
}) => boolean;
methodCall2: (args: { flag: boolean }) => boolean;
}
推荐阅读
- api - 用于将用户或组添加为团队管理员的 Azure DevOps Api
- ruby - 每个打开连接的 EventMachine 计时器
- java - setFill() & setStroke() 没有正确导入
- sql - SQL 查询 - 返回每个操作系统版本的最高版本计数
- c - 基于变量的字符串
- docker - Kubernetes Nodeport 保留源 IP
- c# - 将 Application Insights API 调用结果转换为通用字典未终止字符串。预期的分隔符
- azure-api-management - 如何在 Azure API 管理中的每个请求后关闭 SSL 连接
- java - 使用可选的尾随截断零将字符串解析为 LocalDateTime
- c++ - 在 C++ 中将 3D .obj 文件转换为 .jpg 图像文件