我正在尝试创建一个方法,该方法接收给定类的某些方法名称(作为字符串)作为参数。
例如,如果我有以下代码:
class A {
private member1: string;
public member2: number;
method1() {
//something
}
method2() {
//something
}
propMethod = () => {
//prop method something
}
}
type OnlyClassMethods<T> = T; // need the correct type here
const a = new A();
function callMethod(methodName: OnlyClassMethods<A>) {
// methodName is of type "method1" | "method2"
a[methodName](); // to call this
}
然后methodName将被正确解析,并且智能感知将知道这确实是A的方法。 实际上,我将使用方法名称进行模拟,因此我并没有真正调用它(因此,无论参数传递或返回值如何,此方法都应捕获任何方法),但我仍要确保它仅存在于方法上班级。
编辑:我设法通过类方法和属性方法来解决我的特定问题,但是我将把这个问题留给其他人。有关还可以区分这两种类型的解决方案,请参见下面的Karol Majewski's解决方案
答案 0 :(得分:3)
您需要的类型是:
type OnlyClassMethods<T> = {
[K in keyof T]: [K] extends (...args: any[]) => any ? : never
}[keyof T]
callMethod('method1') // ok
callMethod('foo') // error
callMethod('member1')// error
这是一个非常普遍的mapped type,其中排除了非功能性属性名称。
答案 1 :(得分:1)
可以在适当的方法和类属性之间进行区分,但是它需要this
的显式类型注释。考虑以下示例:
type FunctionPropertyOf<T> = {
[P in keyof T]: T[P] extends Function
? P
: never
}[keyof T]
type MethodOf<T> = {
[P in keyof T]: T[P] extends (this: infer U) => any
? U extends T
? P
: never
: never
}[keyof T]
用法:
class Foo {
bar(this: Foo) {}
baz = () => {}
}
type T1 = FunctionPropertyOf<Foo> // "bar" | "baz"
type T2 = MethodOf<Foo> // "bar"