如何让TypeScript接口严格遵循GlanceOsComparatorV2映射类型?
如何让TypeScript接口严格匹配指定的键类型?
问题背景
已定义以下TypeScript类型和接口:
interface DonutData { label: string; value: number; } interface ProjectMetric { value: number; } enum ZoneMetricId { ClickRate = 'clickRate', } enum PageMetricId { ActivityRate = 'activityRate', BounceRate = 'bounceRate' } type MetricId = | ZoneMetricId | PageMetricId type MetricLabel = 'device' | 'appVersion'; type GlanceKeyCustomV2 = `${MetricId}-${MetricLabel}-app`; type GlanceKeyV2 = GlanceKeyCustomV2 | MetricId; type GlanceOsComparatorV2<T> = { [to in GlanceKeyV2]: T | DonutData[]; }
需要声明接口GlanceOsComparator,使其完全符合GlanceOsComparatorV2<ProjectMetric>的结构要求(示例如下),并且添加不属于GlanceKeyV2的属性(如'test-error')时,TypeScript会抛出类型错误:
interface GlanceOsComparator { ['clickRate-device-app']: DonutData[]; ['clickRate-appVersion-app']: DonutData[]; [ZoneMetricId.ClickRate]: ProjectMetric; };
解决方案
方法1:使用satisfies运算符(TypeScript 4.9+ 推荐)
直接在接口声明末尾添加satisfies关键字,指定接口必须匹配GlanceOsComparatorV2<ProjectMetric>类型。这样既保留接口自身的具体属性类型,又能严格检查所有键是否属于GlanceKeyV2,额外键会直接触发错误:
interface GlanceOsComparator { ['clickRate-device-app']: DonutData[]; ['clickRate-appVersion-app']: DonutData[]; [ZoneMetricId.ClickRate]: ProjectMetric; // 若添加以下属性会报错:类型“{ 'test-error': number; ... }”不满足类型“GlanceOsComparatorV2<ProjectMetric>” // 'test-error': number; } satisfies GlanceOsComparatorV2<ProjectMetric>;
方法2:扩展类型+never索引签名(兼容旧版本TypeScript)
让接口扩展GlanceOsComparatorV2<ProjectMetric>确保合法键的类型正确,同时添加一个索引签名,将所有不属于GlanceKeyV2的键映射为never类型。这样额外属性会因类型不匹配报错:
interface GlanceOsComparator extends GlanceOsComparatorV2<ProjectMetric> { ['clickRate-device-app']: DonutData[]; ['clickRate-appVersion-app']: DonutData[]; [ZoneMetricId.ClickRate]: ProjectMetric; // 限制所有非合法键的类型为never,无法赋值 [key: Exclude<string, GlanceKeyV2>]: never; } // 错误示例:类型“number”不能赋值给类型“never” // const test: GlanceOsComparator = { // ['clickRate-device-app']: [], // ['clickRate-appVersion-app']: [], // clickRate: { value: 1 }, // 'test-error': 123 // };
内容的提问来源于stack exchange,提问作者Nathan Bruet
相关产品推荐
相关产品推荐

