You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过泛型便捷构建组合类型并降低维护成本?

解决方案

基础简化方案:统一维护联合类型

首先将所有IRegisterDemoType实现类型合并为一个单一的联合类型,再通过泛型自动生成组合类型,避免重复手动列举:

export interface IRegisterDemoType<TaskType extends string = string, TaskProps = unknown> {
    key: TaskType;
    props: TaskProps;
}

type Demo1 = IRegisterDemoType<'demo1', {
    value: string;
    another: number;
}>;

type Demo2 = IRegisterDemoType<'demo2', undefined>;

// 统一维护所有Demo类型的联合类型,新增类型只需添加到这里
type AllDemoTypes = Demo1 | Demo2;

interface StoreData<Type extends IRegisterDemoType> {
    storeKey: Type['key'];
    storeProps: Type['props'];
}

interface InstanceData<Type extends IRegisterDemoType> {
    instanceKey: Type['key'];
    instanceProps: Type['props'];
}

// 利用TypeScript的分布式泛型自动生成联合类型,无需手动逐个映射
type AllStoreData = StoreData<AllDemoTypes>;
type AllInstanceData = InstanceData<AllDemoTypes>;

function handleStore(data: AllStoreData) {
    switch (data.storeKey) {
        case 'demo1': {
            console.log(data.storeProps); // 类型依然正确窄化为{ value: string; another: number }
            break;
        }
        case 'demo2': {
            console.log(data.storeProps); // 类型为undefined
            break;
        }
    }
}

function handleInstance(data: AllInstanceData) {
    switch (data.instanceKey) {
        case 'demo1': {
            console.log(data.instanceProps); // 类型正确
            break;
        }
    }
}

核心原理:当泛型参数是联合类型时,TypeScript会自动触发分布式行为,将StoreData<Demo1 | Demo2>拆解为StoreData<Demo1> | StoreData<Demo2>,和手动编写的效果完全一致,但维护成本大幅降低——新增类型只需在AllDemoTypes里追加即可。


进阶方案:自动生成所有Demo类型

如果要进一步降低40+类型的维护成本,可以通过类型映射直接从一个配置对象生成所有IRegisterDemoType实现,彻底告别手动定义Demo1、Demo2这类重复类型:

export interface IRegisterDemoType<TaskType extends string = string, TaskProps = unknown> {
    key: TaskType;
    props: TaskProps;
}

// 仅需维护这个映射表:key对应任务标识,值对应props类型
type DemoTypeMap = {
    demo1: { value: string; another: number };
    demo2: undefined;
    // 新增任务直接在这里添加键值对即可
    demo3: { id: number; name: string };
};

// 自动生成所有IRegisterDemoType的联合类型
type AllDemoTypes = {
    [K in keyof DemoTypeMap]: IRegisterDemoType<K, DemoTypeMap[K]>;
}[keyof DemoTypeMap];

interface StoreData<Type extends IRegisterDemoType> {
    storeKey: Type['key'];
    storeProps: Type['props'];
}

interface InstanceData<Type extends IRegisterDemoType> {
    instanceKey: Type['key'];
    instanceProps: Type['props'];
}

// 自动生成组合类型
type AllStoreData = StoreData<AllDemoTypes>;
type AllInstanceData = InstanceData<AllDemoTypes>;

// 类型窄化依然正常工作
function handleStore(data: AllStoreData) {
    switch (data.storeKey) {
        case 'demo3': {
            console.log(data.storeProps.id); // 类型正确识别为number
            break;
        }
    }
}

这个方案的优势是:所有类型定义都集中在DemoTypeMap中,新增或修改任务类型只需修改这一处,其余类型会自动同步更新,完全避免重复劳动。


内容的提问来源于stack exchange,提问作者Manda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:20:06