打字稿:在子方法中覆盖父Class的静态工厂方法
Typescript: Override static factory method of parent Class in Child method
我 运行 遇到了 Typescript 依赖注入的一些问题。在每个 Class 上,我添加了一个工厂静态方法,其中设置了所有依赖项。我这样做是出于测试目的,以便我仍然能够使用 TDD 方法。
现在我 运行 在子 class 中重写父 class 的工厂方法时遇到了一些问题。示例:
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 中的工厂静态方法。
更新: 此问题的相关错误报告,它自动解释了为什么我在工厂方法上使用泛型是:#26298
首先,有一个名为 InstanceType 的预定义 conditional type,它可以帮助您从静态成员推断 class 类型:
public static factory<T extends typeof Parent>(this: T) {
return new this({ a: 'This is a nice Dependency' }) as InstanceType<T>
}
其次,如果您在子 class 中重写一个方法,无论是否为静态方法,它都应该具有兼容的签名,包括通用的东西。
因此,您的代码块可能如下所示(参见 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"]
。但是您必须稍微修改一下代码。
希望对您有所帮助 ;-)
我 运行 遇到了 Typescript 依赖注入的一些问题。在每个 Class 上,我添加了一个工厂静态方法,其中设置了所有依赖项。我这样做是出于测试目的,以便我仍然能够使用 TDD 方法。
现在我 运行 在子 class 中重写父 class 的工厂方法时遇到了一些问题。示例:
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 中的工厂静态方法。
更新: 此问题的相关错误报告,它自动解释了为什么我在工厂方法上使用泛型是:#26298
首先,有一个名为 InstanceType 的预定义 conditional type,它可以帮助您从静态成员推断 class 类型:
public static factory<T extends typeof Parent>(this: T) {
return new this({ a: 'This is a nice Dependency' }) as InstanceType<T>
}
其次,如果您在子 class 中重写一个方法,无论是否为静态方法,它都应该具有兼容的签名,包括通用的东西。
因此,您的代码块可能如下所示(参见 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"]
。但是您必须稍微修改一下代码。
希望对您有所帮助 ;-)