TypeScript对象类型推断报错:分组函数类型定义问题
问题分析与解决方案
你的代码存在两个核心问题,既导致了类型报错,也无法实现预期的键分组推断:
- 分组逻辑错误:你在
GroupedObject类型中错误地基于对象的值(T[K])拆分分组,但实际需求是根据对象的键(比如color-background-primary这类键的前缀)来分组。 - 未处理symbol键:
keyof T默认包含string | number | symbol类型,而symbol无法用于模板字符串匹配,直接引发类型兼容性错误。
以下是修正后的完整代码:
// 修正后的分组类型:基于键的前缀实现分组 type GroupedObject<T extends Record<string, string>> = { // 从字符串键中提取分组名 [Group in Extract<keyof T, string> extends `${infer G}-${infer Rest}` ? G : never]: { // 筛选当前分组下的所有键 [Key in Extract<keyof T, string> as Key extends `${Group}-${infer Rest}` ? Key : never]: T[Key] } } export function groupObjectByPattern<T extends Record<string, string>>(obj: T): GroupedObject<T> { const groupedObject = {} as GroupedObject<T> for (const key in obj) { const [group] = key.split('-') // 过滤无分组前缀的键(如非xxx-xxx格式的键) if (!group) continue const groupKey = group as keyof GroupedObject<T> if (!groupedObject[groupKey]) { groupedObject[groupKey] = {} as GroupedObject<T>[typeof groupKey] } groupedObject[groupKey][key] = obj[key] } return groupedObject }
效果验证
用你提供的输入对象测试,类型推断完全符合预期:
const inputObject = { "color-background-primary": "#ffffff", "color-background-secondary": "#f3f4f4", "color-background-tertiary": "#e4e7e7", "color-background-interactive": "#0b968f", "color-background-hover": "#026661", "color-background-active": "#2079c3", "font-primary": "foo", "space-xs": "xs", }; const groupedObject = groupObjectByPattern(inputObject); // 自动推断出color分组下的所有键值对 groupedObject.color; // { // "color-background-primary": string; // "color-background-secondary": string; // "color-background-tertiary": string; // "color-background-interactive": string; // "color-background-hover": string; // "color-background-active": string; // } groupedObject.font; // { "font-primary": string } groupedObject.space; // { "space-xs": string }
关键修正说明
- 用
Extract<keyof T, string>过滤掉symbol类型的键,确保仅处理字符串格式的键 - 将分组逻辑从基于值改为基于键,通过模板字符串匹配
Key extends${Group}-${infer Rest}``筛选对应分组的键 - 函数内部使用更精准的类型断言,避免类型不兼容问题
内容的提问来源于stack exchange,提问作者nas.engineer
相关产品推荐
相关产品推荐

