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

如何在TypeScript中基于字面量值创建条件映射类型?

问题解决:基于StreamDefinition生成条件映射类型

原始代码定义

interface StreamDefinition<D> {
    parser: (data: Record<string, string>) => D | null;
    streamType: string;
    defaultStreamName: string;
    patternStream: boolean;
}

const aStreamDefinition: StreamDefinition<number> = {
    parser: (data) => parseInt(data['val']),
    streamType: 'streamA',
    defaultStreamName: 'data:A',
    patternStream: false,
};

const bStreamDefinition: StreamDefinition<string> = {
    parser: (data) => data['val'],
    streamType: 'StreamB',
    defaultStreamName: 'data:B:*:stream',
    patternStream: true,
};

export const streams = {
    A: aStreamDefinition,
    B: bStreamDefinition,
};
type StreamsDefinitions = typeof streams;

需求

生成映射类型FinalDataType,包含streams的所有键,值规则:

  • 若对应StreamDefinition的patternStream为true,值为{[key: string]: D}(D为parser返回的非null类型)
  • 若patternStream为false,值为D本身

现有代码问题

你的条件类型全部返回字典类型,原因是StreamsDefinitions[T]['patternStream']被推断为宽泛的boolean类型,而非具体的true/false字面量,导致条件判断永远走else分支。

解决方案

步骤1:保留patternStream的字面量类型

给streams添加as const断言,让TypeScript保留每个patternStream的具体字面量值:

export const streams = {
    A: aStreamDefinition,
    B: bStreamDefinition,
} as const;

步骤2:修正条件映射类型

由于parser返回D | null,用Exclude剔除null类型,得到纯净的D类型:

type FinalDataType = {
    [T in keyof StreamsDefinitions]: 
        StreamsDefinitions[T]['patternStream'] extends true
            ? { [key: string]: Exclude<ReturnType<StreamsDefinitions[T]['parser']>, null> }
            : Exclude<ReturnType<StreamsDefinitions[T]['parser']>, null>;
};

验证

此时FinalDataType的类型为:

type FinalDataType = {
    A: number;
    B: { [key: string]: string; };
}

完全符合示例对象的类型要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:25:22