是否可以在运行时迭代Typescript类抽象方法?

时间:2018-03-26 08:36:30

标签: javascript typescript oop

我需要知道类的抽象方法列表(实际上所有方法包括抽象方法)。是否有可能以某种方式使用Typescript?

export abstract class INotificationService {
     abstract dismissRequested();
}

console.log(Object.getMethodsList(INotificationService));

预期结果:[' dismissRequested',...]

1 个答案:

答案 0 :(得分:1)

没有为抽象方法生成代码,因此没有直接的方法来获取方法。您可以创建一个虚拟实现并从中获取函数:

abstract class INotificationService {

    abstract dismissRequested(): void;
}

function getMethods<T>(cls: new (...args: any[]) => T): string[] {
    return Object.getOwnPropertyNames(cls.prototype).filter(c=> c!=="constructor");
}

var methods = getMethods<INotificationService>(class extends INotificationService {
    dismissRequested(): void {
        throw new Error("Method not implemented.");
    }
});

如果我们希望我们可以通过禁止虚拟实现类来获得任何新方法来使这更安全一些。这将阻止我们忘记从抽象类中删除的旧方法,尽管虚拟实现可能会覆盖非抽象的现有类方法,因此请小心使用:

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
function getMethods<T>(): <TResult>(cls: new (...args: any[]) => TResult & { [ P in Diff<keyof TResult, keyof T>]: never }) => string[] {
    return cls => Object.getOwnPropertyNames(cls.prototype).filter(c=> c!=="constructor");
}

abstract class INotificationService {

    abstract dismissRequested(): void;
    nonAbstarct(): void {}
}
var methods = getMethods<INotificationService>()(class extends INotificationService {
    // Implement abstract methods, although it is possible to add other methods as well and the compiler will not complain 
    dismissRequested(): void {
        throw new Error("Method not implemented.");
    }
});


// Will cause an error
var methods2 = getMethods<INotificationService>()(class extends INotificationService {
    dismissRequested(): void {
        throw new Error("Method not implemented.");
    } 
    oldDismissRequested(): void {
        throw new Error("Method not implemented.");
    }
});
// Will NOT cause an error
var methods3 = getMethods<INotificationService>()(class extends INotificationService {
    dismissRequested(): void {
        throw new Error("Method not implemented.");
    } 
    nonAbstarct(): void {
        throw new Error("Method not implemented.");
    }
});