TypeScript动态类型键选择:关联manager与methodName类型
解决TypeScript中关联manager与对应methodName的类型提示问题
你当前的问题出在Interface的类型定义逻辑上:T是"A" | "B" | "C"的联合类型,typeof X[T]会被TS推断为三个对象的交叉类型——因为TS无法确定你具体选中的是哪个manager,交叉后如果没有共同属性,keyof typeof X[T]就会变成never,导致methodName没有可用提示。
下面提供两种能实现需求的解决方案,且都支持新增manager或方法时自动更新类型,无需手动维护:
方案1:泛型接口绑定关联关系
通过泛型参数把manager的具体类型和对应的methodName绑定,让TS能根据选中的manager自动推断可用方法:
import * as X from './index.ts'; type ManagerKeys = keyof typeof X; // 泛型接口,用T约束manager的具体类型 interface Interface<T extends ManagerKeys> extends Record<string, unknown> { version: number; manager: T; methodName: keyof typeof X[T]; } // 函数接收泛型参数,TS会自动推断类型 function logManagerUsage<T extends ManagerKeys>(params: Interface<T>) { // 日志记录逻辑 } // 使用示例:选好manager后,methodName会自动弹出对应方法提示 logManagerUsage({ version: 1, manager: 'A', methodName: 'func1' }); logManagerUsage({ version: 1, manager: 'B', methodName: 'func2' });
方案2:生成分布式联合类型
直接生成包含所有合法manager-methodName组合的联合类型,每个组合都是独立的类型分支,TS会自动校验并给出提示:
import * as X from './index.ts'; type ManagerKeys = keyof typeof X; // 遍历所有manager,生成对应类型后合并为联合类型 type Interface = { [T in ManagerKeys]: { version: number; manager: T; methodName: keyof typeof X[T]; } }[ManagerKeys] & Record<string, unknown>; function logManagerUsage(params: Interface) { // 日志记录逻辑 } // 使用示例:选中manager后,methodName仅显示该manager下的可用方法 logManagerUsage({ version: 1, manager: 'C', methodName: 'func1' }); logManagerUsage({ version: 1, manager: 'A', methodName: 'func2' });
以上两种方案都能满足你的需求:开发者编写代码时能获得精准的类型提示,后续新增manager或方法时,TS会自动更新类型定义,无需手动修改接口。
内容的提问来源于stack exchange,提问作者JanithaR
相关产品推荐
相关产品推荐

