关于您的基本示例,您可以通过类型推断以这种方式来检查所提供函数的类型安全性。(
check it on Typescript Playground
):
const a = function <U, V>(myFunc: (arg1: U, arg2: V) => any, arg1: U, arg2: V) {
return myFunc(arg1, arg2)
}
const doubleIfTrue = (arg1: number, arg2: boolean) => arg2 ? 2 * arg1 : arg1
console.log(a(doubleIfTrue, 1, true)) // Type OK
console.log(a(doubleIfTrue, 1, "hop")) // Wrong type: number and string provided
在这种情况下,
U
和
V
根据所提供函数的参数推断类型。
但是你想要达到的目标会变得更加复杂。根据你的代码,我可以解决一些问题(
check it on Typescript Playground
):
type algorithm<OPT = null> = (input: number, options?: OPT) => number;
type algorithmOptions<A> = A extends algorithm<infer OPT> ? OPT : null
const createHandler = <A extends algorithm<any>>(algorithm: A, options: algorithmOptions<A>) =>
(input: number) => algorithm(input, options);
// Algorithms
const addOne:algorithm = (input: number) => input + 1;
interface PowerOptions { value: number; }
const power:algorithm<PowerOptions> = (input: number, {value}) => input ** value
// Handlers
const squaredHandler = createHandler(power, { value: 2 }); // correct
const addOneHandler = createHandler(addOne, null); // correct if a second argument is provided
const addOneHandlerFailing = createHandler(addOne, { value: 2 }); // wrong because an argument is provided
const squaredHandlerFailing1 = createHandler(power, {}); // wrong because of argument interface not respected
const squaredHandlerFailing2 = createHandler(power); // wrong because no argument provided
有一些
conditional type
检索算法参数。但也许我走得太远了,你可以找到一个更简单的方法
另一件事:据我所知,似乎
createHandler
在某些情况下不能是可选的,而在另一些情况下则是强制的,这样就不会使示例变得更复杂。
希望有帮助!