首页 > 解决方案 > TypeScript 将类型别名与继承和泛型结合起来

问题描述

我的代码中有一些深度继承的类,并结合了泛型和组合。在许多使用为相同层次结构组合定制的服务的高级类中,我被迫为每种类型指定完整的层次结构,尽管它可以从我已经定义的类型中推断出来,这使得代码难以阅读,难以理解正确且难以维护(例如,当我想切换一种类型时,我需要在所有地方都这样做)。

我正在考虑在我的文件中使用类型定义,但结合泛型,因为它是在类之外定义的,所以我很难实现这一点。

这是该问题的最小化示例:

export class BaseLine {
}

export class BaseHeader<TLines extends BaseLine> {
    lines: TLines[];
}

export class ServiceA
    <THeader extends BaseHeader<TLines>,
    TLines extends BaseLine> {
}

export class ServiceB
    <THeader extends BaseHeader<TLines>,
    TLines extends BaseLine> {
}

export class HeaderDetail 
    <THeader extends BaseHeader<TLines>,
    TLines extends BaseLine> {
    serviceA: ServiceA<THeader, TLines>;
    serviceB: ServiceB<THeader, TLines>;
}

现在想象一个类有超过 2 个泛型类型,超过 2 个服务,我得到一个包含一半类型的文件。类型别名在这里真的可以发挥作用,我真正想做的是:

type TLines = any extends BaseLine;
export class BaseHeader<TLines> {
    lines: TLines[];
}

type TLines = any extends BaseLine;
type THeader = any extends BaseHeader<TLines>;
export class ServiceA <THeader> {
}

type TLines = any extends BaseLine;
type THeader = any extends BaseHeader<TLines>;
export class Service <THeader> {
}

type TLines = any extends BaseLine;
type THeader = any extends BaseHeader<TLines>;
export class HeaderDetail <THeader> {
    serviceA: ServiceA<THeader>;
    serviceB: ServiceB<THeader>;
}

但是,我找不到正确的方法,ts 不断给我们神秘的错误:'?预期的,我假设这是因为不应像在类型别名中那样使用扩展语法。

有没有办法让类型别名像那样工作?有没有可能更好的方法来做到这一点?(不创建更多类型..)

标签: typescriptgenericsinheritancecompositiontype-alias

解决方案


您不需要将链中的每个变量都设为泛型。相反,您可以使用一个泛型来引用最高对象(THeader而不是TLines)。

export class HeaderDetail <THeader extends BaseHeader<any>> {
}

如果你想访问 的类型TLines,你可以通过向后工作来获得它。

type HeaderLines<THeader> = THeader extends BaseHeader<infer TLines> ? TLines : never;
export class ServiceA <THeader extends BaseHeader<any>> {
    lines: HeaderLines<THeader>[];

    constructor( header: THeader ) {
        this.lines = header.lines;
    }
}

打字稿游乐场链接


推荐阅读