typescript 强制类型别名

kb5ga3dv  于 2023-02-17  发布在  TypeScript
关注(0)|答案(1)|浏览(129)

我们为Typescript构建了一个类型生成器,它输出的类型如下所示:

type Def$9f45cffb = {
    'title': string,
    'subtitle': string,
    'cta': Def$3f75f612,
};

type Def$3f75f612 = {
    'variant': 'primary' | 'secondary',
    'label': string,
    'link': string,
};

type Def$46b580bc = {
    'title': string,
    'subtitle'?: string,
    'cta': Def$3f75f612,
};

declare module 'component' {
    type VerticalBannerV1_0 = Def$9f45cffb;

    export interface VersionedComponentMap {
        'vertical-banner': {
            latest: VerticalBannerV1_0,
            '1.0': VerticalBannerV1_0,
        };
    }
}

declare module 'slot' {
    type HomeBannerV1_0 = Def$46b580bc;
    type HomeBannerV2_0 = Def$9f45cffb;

    export interface VersionedSlotMap {
        'home-banner': {
            latest: HomeBannerV2_0,
            '1.0': HomeBannerV1_0,
            '2.0': HomeBannerV2_0,
        };
    }
}

注意,类型在两个Map之间被重用以避免重复,这样做效果很好,除了别名被扩展,使得调试成为一场噩梦:

我知道TypeScript不提供保留类型别名的保证。我正在寻找解决此问题的方法,以提供更好的开发人员体验。
例如,我的目标是防止别名被扩展,这样HomeBannerV2_0就不会变成Def$46b580bc
这是我目前得到的type example = VersionedSlotMap['home-banner'][keyof VersionedSlotMap['home-banner']]; }

Def$46b580bc | Def$9f45cffb

这就是我想要的

HomeBannerV1_0 | HomeBannerV2_0
pw136qt2

pw136qt21#

我发现使用递归实用程序标记类型,然后删除该标记是有效的:

const Complicated = Symbol();

type Complicated<T> = Omit<T & { [Complicated]: Complicated<T> }, typeof Complicated>;

用法:

// Hovering over types with `IWantToSeeThis` only displays `IWantToSeeThis`
type IWantToSeeThis = Complicated<IDontWantToSeeThis>;

然而,这只适用于原语和对象,数组和元组将不起作用,函数将被简化为{}
你可以通过 * 保留 * 标签来绕过这个问题:

type Complicated<T> = T & { [Complicated]: Complicated<T> };

但是当你试图给这个类型赋值时就会有问题。
上面简单示例的Playground
代码的Playground

相关问题