传播类功能

时间:2018-10-10 05:48:21

标签: javascript typescript

是否有一种方法可以将类的功能扩展到另一个对象中?作为一个人为的例子:

class FooBar {
    private service: MyService;

    constructor(svc: MyService) {
       this.service = svc;
    }

    public foo(): string {
        return "foo";
    }

    public bar(): string {
        return "bar"
    }

    public fooBar(): string {
        return "foobar"
    }
}

let obj = new FooBar();

export default {
    ...obj
};

我希望导出的对象包含类FooBar的所有方法,而不包含私有属性service。但是,这些方法在编译为javascript时会放置在原型对象上,因此它们不会包含在传播操作中,并且私有属性包含在对象中,因为它位于结果对象中。

我知道我可以做到:

export default {
    foo: obj.foo.bind(obj),
    bar: obj.bar.bind(obj),
    fooBar: obj.fooBar.bind(obj),
};

如果可能的话,我想避免这种情况,因为我将有多个类的方法可以映射。

注意:这用于将GraphQL解析器组合到单个对象中,该对象将提供给graphql函数。

如果有任何不同,我正在使用ts-node运行我的应用。

1 个答案:

答案 0 :(得分:0)

我遇到了几个问题。首先,我将es6而不是es5作为输出。这样做会导致在已编译对象上没有原型。

第二,仅进行传播会导致私有属性service被包含在导出的对象中。我最终编写了@Vivick和@AlekseyL所暗示的辅助函数。

function combineResolvers(...resolvers: any[]): any {
    let out: { [key: string]: any } = {}
    resolvers.forEach(resolver => {
        let proto = Object.getPrototypeOf(resolver)
        Object.keys(proto)
            .filter(key => {
                return isFunction(resolver[key]);
            }).forEach(key => {
                out[key] = resolver[key].bind(resolver)
            })
    })

    return out
}

function isFunction(functionToCheck: any): boolean {
    return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

这仍然存在将解析器类上的任何私有函数包含到导出对象中的问题。