映射类型泛型内嵌套映射类型功能正常但TS报错排查
问题解决:TypeScript泛型索引类型报错修复
错误原因
你遇到的Type 'T[key]' is not assignable to type 'string | number | symbol'报错,是因为TypeScript无法确认泛型T的属性值T[key]一定是合法的对象键类型。虽然你给T加了extends Record<"albums" | "tracks", string>约束,但宽泛的string类型不足以让TypeScript推断出T[key]是符合要求的键类型(尽管实际使用的是字符串字面量),所以类型检查器会抛出错误。
解决方案
将泛型约束中的string替换为TypeScript内置的PropertyKey类型别名(等价于string | number | symbol),明确告知TypeScriptT的属性值只能是合法的对象键类型:
// 修正后的工具类型,无报错 type makeSortOptions<T extends Record<"albums" | "tracks", PropertyKey>> = { [key in keyof T]: { [value in T[key]]: "ascending" | "descending" } } type SortOptions = makeSortOptions< { albums: "title" tracks: "title" | "artist" } > // 依然符合预期类型 const x: SortOptions = { albums: { title: "descending" }, tracks: { artist: "descending", title: "ascending", }, } // 依然无法通过类型检查,符合预期 const y: SortOptions = { albums: { title: "space and time" }, tracks: { artist: "foo", bar: "ascending", }, }
原理说明
PropertyKey是TypeScript内置的类型,专门用来表示合法的对象键类型。通过将泛型约束改为T extends Record<"albums" | "tracks", PropertyKey>,TypeScript可以确定T[key]必然是string | number | symbol中的一种,因此在定义嵌套索引类型{ [value in T[key]]: ... }时不会再触发类型错误,同时完整保留你原本需要的功能。
内容的提问来源于stack exchange,提问作者Woww
相关产品推荐
相关产品推荐

