代码之家  ›  专栏  ›  技术社区  ›  Get Off My Lawn

如何将一个新的this从静态方法传递给静态方法?

  •  0
  • Get Off My Lawn  · 技术社区  · 5 年前

    我如何通过一个新的 this

    TypeScript Playground

    abstract class Model {
      public static convert<T extends Model>(model: new () => T, data: any | any[]) { 
        return new model()
      }
    
      public static all<T extends Model>(): Promise<[]> {
        let items: any[] = []
        return Model.convert(this, items)
                          // ^--- Error is here
      }
    }
    

    A ,但是typescript抱怨此错误:

    “type of Model”类型的参数不能分配给“new()=>Model”类型的参数。

    class Model {
        static convert(model, data) { return new model() }
        static all() {
            let items = [];
            return Model.convert(this, items);
        }
    }
    
    class A extends Model { }
    
    console.log(A.all(), A.all().constructor.name);
    0 回复  |  直到 5 年前
        1
  •  3
  •   Titian Cernicova-Dragomir    5 年前

    如果 Model 不是 abstract . 如果 不是抽象的 this (打印为 typeof Model )会有 new () => Model

    简单的解决方案是为

    abstract class Model {
      public static convert<T extends Model>(model: new () => T, data: any | any[]): T[] { return null!; }
    
      public static all<T extends Model>(this: new () => T): Promise<T[]> {
        let items: any[] = []
        return Promise.resolve(Model.convert(this, items));
      }
    }
    
    class A extends Model { }
    
    
    console.log(Model.all()) // err since Model does not have a ctor
    console.log(A.all(), A.all().constructor.name)
    

    Play

    这将使 all 无法呼叫 模型 不管怎样,这可能是你想要的。

    因为在实际的用例中,您希望从其他静态方法调用静态方法,所以我们需要一个稍微复杂一点的注释 型号 在注释中。最简单的方法是 型号 (new () => T) )基本上是向抽象类添加构造函数。

    
    type NonAbstracModel<T extends Model> = (new () => T) & typeof Model
    abstract class Model {
      public static convert<T extends Model>(model: NonAbstracModel<T>, data: any | any[]): T { return new model() }
    
      public static all<T extends Model>(this: NonAbstracModel<T>): T {
        let items: any[] = []
        return Model.convert(this, items)
      }
    
      public static find<T extends Model>(this: NonAbstracModel<T>, primaryKey: string | object) { }
    
      public static firstOrFail<T extends Model>(this:NonAbstracModel<T>) {
        this.find('abc')
      }
    
    }
    
    class A extends Model {}
    
    console.log(A.all(), A.all().constructor.name)