从泛型函数创建泛型类型
create generic type from generic function
我正在尝试基于另一个泛型类型声明一个泛型类型但没有成功。
objective是我自己编写的测试框架,并根据另一个框架(方法)键入一些参数。
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
.
可以找到游乐场here。
谢谢!
如果我没理解错的话,你已经很接近了。您可以在函数语法(定义 methodCall
的签名就像定义函数实现一样)和 属性 语法(定义 methodCall
为 属性 恰好是一个 lambda,这与你拥有它的方式很接近)。
如果使用函数语法,则在尖括号 (<>
) 中定义泛型,在括号之间定义参数列表,冒号后的 return 类型;就好像你在定义一个没有主体的函数。如果使用 属性 语法,则定义了一个 lambda,泛型位于尖括号中,参数列表位于圆括号中,return 类型位于粗箭头之后(=>
);您正在使用该名称定义 属性 并将您的类型 - a function type - 放在冒号之后。无论哪种方式都适合你。
(我还从您的自定义 Arguments
实用程序类型切换到 the undocumented Parameters
built-in。)
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;
}
我正在尝试基于另一个泛型类型声明一个泛型类型但没有成功。
objective是我自己编写的测试框架,并根据另一个框架(方法)键入一些参数。
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
.
可以找到游乐场here。
谢谢!
如果我没理解错的话,你已经很接近了。您可以在函数语法(定义 methodCall
的签名就像定义函数实现一样)和 属性 语法(定义 methodCall
为 属性 恰好是一个 lambda,这与你拥有它的方式很接近)。
如果使用函数语法,则在尖括号 (<>
) 中定义泛型,在括号之间定义参数列表,冒号后的 return 类型;就好像你在定义一个没有主体的函数。如果使用 属性 语法,则定义了一个 lambda,泛型位于尖括号中,参数列表位于圆括号中,return 类型位于粗箭头之后(=>
);您正在使用该名称定义 属性 并将您的类型 - a function type - 放在冒号之后。无论哪种方式都适合你。
(我还从您的自定义 Arguments
实用程序类型切换到 the undocumented Parameters
built-in。)
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;
}