【问题标题】:Typescript: Override static factory method of parent Class in Child method打字稿:在子方法中覆盖父类的静态工厂方法
【发布时间】:2019-01-15 15:47:23
【问题描述】:

我在使用 Typescript 进行依赖注入时遇到了一些问题。在每个类上,我添加了一个工厂静态方法,其中设置了所有依赖项。我这样做是为了测试目的,以便我仍然能够使用 TDD 方法。

现在我在子类中重写父类的工厂方法时遇到了一些问题。示例:

interface DepsA {
  a: string
}

interface DepsB extends DepsA {
  b: Child1
}

class Parent {
  constructor(protected deps: DepsA | DepsB) {}

  public static factory<T extends Parent>() {
    return new this({a: 'This is a nice Dependency'}) as T
  }
}

class Child1 extends Parent {}

class Child2 extends Parent {
  public static factory() {
    return new this({a: 'This is a nice Dependency', b: Child1.factory()})
  }
}

const child1 = Child1.factory<Child1>()
const child2 = Child2.factory()

我收到的错误是:

[ts]
Class static side 'typeof Child2' incorrectly extends base class static side 'typeof Parent'.
  Types of property 'factory' are incompatible.
    Type '() => Child2' is not assignable to type '<T extends Parent>() => T'.
      Type 'Child2' is not assignable to type 'T'.

我知道我为什么会收到错误,但现在不知道如何修复它,除了重命名 Child2 中的工厂静态方法。

更新: 与此问题相关的错误报告,自动解释了为什么我在工厂方法上使用 Generic 是:#26298

【问题讨论】:

    标签: node.js typescript oop dependency-injection tdd


    【解决方案1】:

    首先,有一个名为 InstanceType 的预定义 conditional type 可以帮助您从静态成员推断类类型:

    public static factory<T extends typeof Parent>(this: T) {
        return new this({ a: 'This is a nice Dependency' }) as InstanceType<T>
    }
    

    其次,如果你在子类中重写了一个方法,不管是不是静态的,它应该有一个兼容的签名,包括通用的东西。

    因此,您的代码块可能如下所示(参见Typescript Playground):

    interface DepsA {
        a: string
    }
    
    interface DepsB extends DepsA {
        b: Child1
    }
    
    class Parent {
        constructor(public deps: DepsA | DepsB) {}
    
        public static factory<T extends typeof Parent>(this: T) {
            return new this({ a: 'This is a nice Dependency' }) as InstanceType<T>
        }
    }
    
    class Child1 extends Parent {}
    
    class Child2 extends Parent {
        public static factory<T extends typeof Parent>(this: T) {
            return new this({a: 'This is a nice Dependency', b: Child1.factory()}) as InstanceType<T>
        }
    }
    
    const child1 = Child1.factory()  // Type: Child1
    const child2 = Child2.factory()  // Type: Child2
    

    从那里返回正确的deps 类型,而不是联合,也可以在非静态成员中使用as this["deps"]。但是你必须修改你的代码。

    希望对你有帮助 ;-)

    【讨论】:

    • 如果您只是要在最后断言子类型,为什么还要费心将方法设为通用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    相关资源
    最近更新 更多