如何实现TypeScript泛型中动态嵌套键的正确类型推导?
解决TypeScript动态嵌套键的类型标注问题
原代码问题分析
你的FiltersProps泛型定义存在两个核心问题:
- 泛型参数
X extends keyof M完全无效——M是T的顶层键(字符串类型),keyof M的结果是never,这个参数没有实际作用。 values的键定义错误:[K in M]会把顶层键(比如示例中的statuses)作为values的键,而不是你期望的顶层键对应的嵌套子键(done/expired)。
修正后的类型定义
首先调整Config和FiltersProps的类型,让values的键自动对应config中指定顶层键的嵌套子键:
// 如果允许options可选(适配你示例中的空对象),调整Config类型 export type Config = { [TopKey: string]: { [SubKey: string]: { options?: string[]; type?: 'checkbox' | 'toggle'; }; }; }; // 重新定义FiltersProps:仅保留必要的泛型参数 export interface FiltersProps<T extends Config, TopKey extends keyof T> { config: T; values: { // 取T[TopKey]的所有子键作为values的键,类型固定为string[] [SubKey in keyof T[TopKey]]: string[]; }; }
自动推导类型的实现
直接声明对象时TypeScript不会自动应用泛型约束,建议用一个辅助函数来自动推导泛型参数:
// 辅助函数,用于自动推导泛型 function createFiltersProps<T extends Config, TopKey extends keyof T>(props: FiltersProps<T, TopKey>) { return props; }
使用示例
const config = { statuses: { done: {}, expired: {}, }, }; // 自动推导类型,values的键只能是done/expired,值必须是string[] const filterProps = createFiltersProps({ config, values: { done: [], // 正确类型标注:string[] expired: [], // 正确类型标注:string[] // 若添加不存在的键(如'active'),TypeScript会直接报错 }, });
额外说明
如果你的Config要求options为必填项,只需把options?: string[]改回options: string[],同时确保示例中的done/expired对象包含options属性即可。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

