【发布时间】:2018-06-03 09:53:34
【问题描述】:
例子
class BaseOptions {
a: 1;
}
class OptionsA extends BaseOptions {
b: 2;
}
class OptionsB extends BaseOptions {
c: 3;
}
class Child<TOptions extends BaseOptions> {
options: TOptions;
}
// Parent must use a child that supports TOptions
class Parent<TOptions extends BaseOptions, TChild extends Child<TOptions>> { }
// Supports OptionsA
class StrictChild extends Child<OptionsA> { }
// Supports OptionsA and OptionsB
class FlexibleChild extends Child<OptionsA | OptionsB> {
doSomething() {
if (this.options instanceof OptionsA) {
const test1 = this.options.b;
}
// This should fail because no instanceof check
const test2 = this.options.c;
}
}
// Expected to fail because StrictChild can't have OptionsB
const parentA = new Parent<OptionsB, StrictChild>();
// Expected to pass because FlexibleChild can have OptionsA or OptionsB
// but fails because "OptionsA" is not assignable to "OptionsA | OptionsB"
const parentB = new Parent<OptionsB, FlexibleChild>();
我认为问题是
class Parent<TOptions extends BaseOptions, TChild extends Child<TOptions>> { }
特别是Child<TOptions>,因为我认为它需要类似于Child<TOptions extends Child<T>>,但我不知道该怎么做。
【问题讨论】:
-
这不符合预期吗?
OptionsA | OptionsB表示子级可以拥有options属性,即OptionsA,因此与Parent<OptionsB, FlexibleChild>中的OptionsB不兼容。灵活的孩子不会是FlexibleChild extends Child<OptionsA & OptionsB>吗?也就是说,目前,FlexibleChild更像是一个不知名的孩子,这就是问题所在 - TypeScript 不知道options是否是OptionsB。 -
@cartant 嗯,我认为这不太对,如果您使用 & 那么您可以使用
this.options.b和this.options.c而不检查它们是否存在。其目的是FlexibleChild支持 OptionsA 或 OptionsB 但不能同时支持两者。 -
如果 OptionsA 是一个类,我的示例可能更有意义,因此您可以检查 instanceof
-
如果是这种情况,错误是完全合适的,你不能做你想做的事。您必须使用
const parentAorB = new Parent<OptionsA | OptionsB, FlexibleChild>();之类的东西,因为不能保证孩子拥有options属性,即OptionsB。 -
但是我们不能通过传递允许 OptionsB 的 FlexibleChild 来保证吗?也许我的结构是错误的。 Parent 将接收 options 对象,然后使用 options 对象创建一个 FlexibleChild 实例。我只想检查传递给 Parent 的选项类和子类是否兼容。
标签: typescript