TypeScript:接口联合类型中属性类型为何会合并?
问题原因
你用IBlockVariationSelectBanners | IBlockVariationSelectColumns作为函数参数类型时,TypeScript会把currentVariation和variationMap当成两个独立的联合类型来看:
currentVariation的类型变成了"default" | "with_image" | "twoColumn"(也就是两个映射的键的合集)variationMap的类型是bannerVariationType | columnVariationTypes
TypeScript没法自动识别这两个参数的绑定关系——它不知道当variationMap是横幅映射时,currentVariation只能是横幅的键;当是列映射时,只能是列的键。所以函数里用currentVariation去索引variationMap时,TypeScript会认为可能出现不匹配的情况(比如用twoColumn去拿横幅映射里的值),导致类型校验报错。
解决方案1:用泛型绑定参数关系
把函数改成泛型函数,让currentVariation的类型严格跟着variationMap的键走:
const bannerVariationMap = { default: { label: "Banner (Center)" }, with_image: { label: "Banner (Right) with image" } }; export const columnVariationMap = { twoColumn: { label: "Two Columns" } }; type bannerVariationType = typeof bannerVariationMap; type columnVariationTypes = typeof columnVariationMap; type VariationMap = bannerVariationType | columnVariationTypes; export const variationSelect = <T extends VariationMap>({ currentVariation, variationMap }: { currentVariation: keyof T; variationMap: T; }) => { return variationMap[currentVariation].label; };
这样TypeScript会根据你传入的variationMap自动推断currentVariation的合法取值,确保两者始终匹配。
解决方案2:给联合类型加区分字段
如果想保留原来的接口结构,可以给两个接口加一个专属的字面量字段,让TypeScript能通过这个字段精准判断参数类型:
const bannerVariationMap = { default: { label: "Banner (Center)" }, with_image: { label: "Banner (Right) with image" } }; export const columnVariationMap = { twoColumn: { label: "Two Columns" } }; type bannerVariationType = typeof bannerVariationMap; type columnVariationTypes = typeof columnVariationMap; interface IBlockVariationSelectBanners { type: 'banner'; // 新增区分字段 currentVariation: keyof bannerVariationType; variationMap: bannerVariationType; } interface IBlockVariationSelectColumns { type: 'column'; // 新增区分字段 currentVariation: keyof columnVariationTypes; variationMap: columnVariationTypes; } type IBlockVariationSelect = IBlockVariationSelectBanners | IBlockVariationSelectColumns; export const variationSelect = (props: IBlockVariationSelect) => { switch (props.type) { case 'banner': return props.variationMap[props.currentVariation].label; case 'column': return props.variationMap[props.currentVariation].label; } };
这种方式通过明确的区分字段,让TypeScript在每个分支里都能确定currentVariation和variationMap的匹配关系,彻底解决类型错误。
内容的提问来源于stack exchange,提问作者Andrej Denisov
相关产品推荐
相关产品推荐

