有条件地在基类上指定方法/道具

时间:2017-12-15 17:41:18

标签: javascript typescript oop

与其他JS开发人员一样,我有点想到以静态方式编写TypeScript编译器可以理解的东西。我的基本用例是自定义通用类上可用的操作以访问REST端点。我可以基于构造函数参数动态地将方法/道具添加到基类,但是动态(可理解)做事情会使智能感知不正确。我知道我只是在考虑这个错误,并且有一种不同的范例可以达到我想要的目的。如何以编译器理解的方式从子代中自定义基类?

以下是我正在尝试的内容:

class Endpoint<T> {
    constructor(
        methods: Array<'GET' | 'CREATE'>
    ) {
        // Conditionally add methods to the endpoint based on what was passed in
        if (methods.includes('GET')) {
            this.get = function get(id: string): Promise<T> {
                return new Promise<T>(resolve => resolve());
            };
        }
        if (methods.includes('CREATE')) {
            this.create = function create(body: T): Promise<T> {
                return new Promise<T>(resolve => resolve());
            };
        }
    }

    public get?: (id: string) => Promise<T>;
    public create?: (body: T) => Promise<T>;
}

class User extends Endpoint<IUser> {
    constructor() {
        super(['GET']);
    }
}

let u = new User();
// u.create will get transpiled away, but still shows up in intellisense

1 个答案:

答案 0 :(得分:1)

您可以缩短此代码并且它不漂亮,但基本的想法是使用在Typescript 2.2中引入的mixins

class Endpoint<T> {
}

type Constructor<T> = new(...args: any[]) => T;

function Gettable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) {
   return class extends Base {
        get(id: string): Promise<T> {
            return new Promise<T>(resolve => resolve());
        }
    }
}

function Createable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) {
    return class extends Base {
        create(body: T): Promise<T> {
            return new Promise<T>(resolve => resolve());
        }
    }
}

class User extends Gettable<IUser>(Endpoint)<IUser> {
}

const u = new User();
u.get("id"); // ok
u.create(); // error, method doesn't exist