我试图基于另一个泛型类型声明一个泛型类型,但没有成功。
目标是编写我自己的测试框架并根据另一个(方法)键入一些参数。
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 的对象能够helpers().methodCall(...)
像在 helpers 中声明的那样输入。不与any
。
操场可以在这里找到。
谢谢!
你很接近,如果我理解正确的话。您可以在函数语法(methodCall
定义函数实现时定义的签名)和属性语法(定义methodCall
为恰好是 lambda 的属性,这与您拥有它的方式相近)之间进行选择。
如果使用函数语法,则在尖括号 ( <>
) 中定义泛型、括号之间的参数列表以及冒号后的返回类型;这就好像你在定义一个没有主体的函数。如果您使用属性语法,您就是在定义一个 lambda,泛型在尖括号中,参数列表在圆括号中,返回类型在粗箭头 ( =>
) 之后;您正在通过该名称定义一个属性,并将您的类型——函数类型——放在冒号之后。无论哪种方式都适合你。
(我还从您的自定义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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句