我正在尝试在Typescript中创建函数签名。它是一种接收对象,其方法名称和要应用的args的调用函数。
使用示例:
const obj = {
do(...args) {
console.log(args);
}
}
call(obj, 'do', 1, 2, 3);
我可以想象有一个简单的签名,该签名定义了第二个参数应该是第一个参数的属性,但是我很难拒绝所有不是方法的属性,并指定可变参数作为该方法的参数。
function call<T, P extends keyof T, A extends any[]>(obj: T, property: P, ...args: A): void;
是否可以使用当前的Typescript做到这一点?
答案 0 :(得分:1)
如果我们使用tuples in rest parameters,提取函数的参数实际上并不是很复杂。实际上,在3.2中,Typescript使用这种方法来实现严格的call
,bind
和apply
(请参见here)
要限制键,我们可以将T
限制为具有P
功能的记录:
const obj = {
do(...args: string[]) {
console.log(args);
},
other(o: string, n: number) {
console.log(o);
},
prop: 1
}
function call<T extends Record<P, (...a: any[]) => any>, P extends keyof T>(obj: T, property: P, ...args: Parameters<T[P]>): ReturnType<T[P]> {
return obj[property](...args);
}
call(obj, 'do', 1, 2, 3); // error
call(obj, 'do', '1'); // ok
call(obj, 'do', '1', '2'); // ok
call(obj, 'other', '1', 2); // ok
call(obj, 'prop'); // error