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

Javascript 有条件地指定基类上的方法/道具,javascript,typescript,oop,Javascript,Typescript,Oop,与其他JS开发人员一样,我对以TypeScript编译器可以理解的静态方式编写东西有些陌生。我的基本用例是自定义泛型类上用于访问REST端点的操作。我可以基于构造函数参数动态地向基类添加方法/道具,但是动态地(可以理解地)做一些事情会使intellisense不正确。我知道我只是在想这个错误,实现我想要的东西有一个不同的范例。如何以编译器理解的方式从基类的子类自定义基类 以下是我正在尝试的: class Endpoint<T> { constructor( m

与其他JS开发人员一样,我对以TypeScript编译器可以理解的静态方式编写东西有些陌生。我的基本用例是自定义泛型类上用于访问REST端点的操作。我可以基于构造函数参数动态地向基类添加方法/道具,但是动态地(可以理解地)做一些事情会使intellisense不正确。我知道我只是在想这个错误,实现我想要的东西有一个不同的范例。如何以编译器理解的方式从基类的子类自定义基类

以下是我正在尝试的:

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
类端点{
建造师(
方法:数组
) {
//根据传入的内容有条件地向端点添加方法
if(methods.includes('GET')){
this.get=函数get(id:string):Promise{
返回新承诺(resolve=>resolve());
};
}
if(methods.includes('CREATE')){
this.create=函数create(body:T):Promise{
返回新承诺(resolve=>resolve());
};
}
}
公共获取?:(id:string)=>承诺;
公共创造?:(正文:T)=>承诺;
}
类用户扩展端点{
构造函数(){
超级(['GET']);
}
}
设u=新用户();
//u.create将被传输出去,但仍然显示在intellisense中

您可能可以缩短此代码,但它并不漂亮,但基本思想是使用Typescript 2.2中引入的代码:

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
类端点{
}
类型构造函数=new(…参数:any[])=>T;
可获取函数(基:U){
返回类扩展了基{
get(id:string):承诺{
返回新承诺(resolve=>resolve());
}
}
}
可创建的函数(基:U){
返回类扩展了基{
创建(body:T):承诺{
返回新承诺(resolve=>resolve());
}
}
}
类用户扩展了Gettable(端点){
}
const u=新用户();
u、 获取(“id”);//好啊
u、 创建();//错误,方法不存在

您是否希望实现一种抽象父类?那么,为什么不定义所需的基类,并为从它扩展的类的所需实现提供额外的接口呢?我不确定我是否遵循。就像在
类中一样,用户扩展端点实现IGettable
?或
让u=new User()作为IGettable
?然后为实例功能的交叉点定义扩展接口,如
IGetCreate
?这似乎奏效了。