如何定义TypeScript接口的键与指定联合类型匹配?
问题解决方案
一、修改ResponseData实现动态键约束
要让ResponseData的键只能是resultTypes中的一个或多个,用映射类型即可实现动态结构约束:
export type resultTypes = 'categories'| 'products'| 'content'| 'files'; // 键为resultTypes的子集,值统一为string[],所有键可选(支持一个或多个键的组合) export type ResponseData = Partial<Record<resultTypes, string[]>>;
如果要求ResponseData必须至少包含一个键(不能是空对象),可以使用更严格的定义:
export type resultTypes = 'categories'| 'products'| 'content'| 'files'; export type ResponseData = { [K in resultTypes]?: string[] } & { [key: string]: never } extends infer O ? { [K in keyof O]: O[K] } : never;
二、解决类型不匹配报错
报错根源是resultTypes包含了ResponseData可能不存在的键(categories、files),而hasResultsOfType函数要求参数是response实际存在的键类型。提供两种解决思路:
思路1:精确缩小类型范围
直接把Object.keys(response)断言为response实际键的数组,而非宽泛的resultTypes[]:
const response: ResponseData = {products: ['r'], content: ['r']}; // 断言为当前response的键类型数组 const currentResultTypes = Object.keys(response) as Array<keyof typeof response>; type typeProperty = keyof typeof response; const hasResultsOfType = (typeProp: typeProperty) => { return typeProp in response && response[typeProp]; }; const typeProp = currentResultTypes[0]; const isValid = hasResultsOfType(typeProp); // 无报错
思路2:在函数内做类型兼容处理
如果需要保留resultTypes类型的参数,在函数内部通过运行时检查+类型断言让TS认可:
const response: ResponseData = {products: ['r'], content: ['r']}; const currentResultTypes = Object.keys(response) as resultTypes[]; const hasResultsOfType = (typeProp: resultTypes) => { // 先检查键是否存在,再通过断言告诉TS类型兼容 return (typeProp as keyof typeof response) in response && response[typeProp as keyof typeof response]; }; const typeProp = currentResultTypes[0]; const isValid = hasResultsOfType(typeProp); // 无报错
额外优化:让类型自动同步
如果想避免手动维护resultTypes和ResponseData的键导致不一致,可以反过来从ResponseData推导resultTypes:
// 先定义包含所有可能键的ResponseData export type ResponseData = { categories?: string[]; products?: string[]; content?: string[]; files?: string[]; }; // 自动推导所有可能的键类型 export type resultTypes = keyof ResponseData;
内容的提问来源于stack exchange,提问作者Galivan
相关产品推荐
相关产品推荐

