Typescript:在另一个类上扩展泛型类型的泛型类型

时间:2018-06-02 02:04:57

标签: typescript

实施例

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>>,但我不知道该怎么做。

Typescript playground

2 个答案:

答案 0 :(得分:1)

我认为只要我在Child上设置默认通用符号就可以使用它,这样我就可以使用TChild [&#39; options&#39;]

class Child<TOptions extends BaseOptions = BaseOptions> {
    options: TOptions;
}

// Parent must use a child that supports TOptions
class Parent<TOptions extends TChild['options'], TChild extends Child> { } 

Typescript Playground

修改

或者你可以做

class Parent<TOptions extends TChild['options'], TChild extends Child<BaseOptions>> { }

答案 1 :(得分:0)

您正在寻找交叉类型,而不是工会类型!

// Supports OptionsA and OptionsB
class FlexibleChild extends Child<OptionsA & OptionsB> { }

现在这是一个非常有效的陈述:

const parentB = new Parent<OptionsB, FlexibleChild>();

参考:https://www.typescriptlang.org/docs/handbook/advanced-types.html

  

交集类型将多种类型合并为一种。这允许您将现有类型添加到一起以获得具有所需功能的单一类型。例如,Person & Serializable & LoggablePersonSerializable以及Loggable。这意味着这种类型的对象将拥有所有三种类型的所有成员。