TypeScript访问对象深层属性时keyof返回never类型如何解决?
问题解决方法
你遇到的类型报错本质是TypeScript对字面量对象的精确推导导致不同服务的commands属性没有公共key,联合后keyof得到never类型,可通过以下几种方案解决:
方案1:定义通用服务类型,放宽类型推导
提前定义通用的命令类和服务结构类型,声明services时主动指定类型,避免TS生成过于精确的无交集类型:
// 定义通用命令类约束:无参构造函数,包含init方法 type Command = new () => { init(): void }; // 定义服务结构 interface Service { commands: Record<string, Command> } // 声明services时指定类型 export const services: Record<string, Service> = { service1: { commands: { a: A } }, service2: { commands: { b: B } } }
后续使用时不需要额外类型断言,直接调用即可:
if (input[1] in commands) { new commands[input[1]](); }
方案2:添加类型守卫,保留精确类型推导
如果需要保留每个服务commands的原有精确类型(不希望用宽泛的Record类型),可以写一个通用类型守卫函数收窄类型:
// 通用类型守卫:判断指定key是否属于对象的合法key function isCommandKey<T extends object>(obj: T, key: string): key is keyof T { return key in obj; }
使用时替换原有判断逻辑:
if (isCommandKey(commands, input[1])) { // 此处TS会自动识别input[1]是commands的合法key,不会出现never报错 new commands[input[1]](); }
方案3:简易类型断言
如果只是临时解决不想修改上层定义,可以直接对取值结果做构造函数类型断言:
if (input[1] in commands) { new (commands[input[1] as keyof typeof commands] as new () => { init: () => void })(); }
内容的提问来源于stack exchange,提问作者LoveDev
相关产品推荐
相关产品推荐

