TypeScript索引报错:字符串无法索引对象类型如何解决?
消除TypeScript索引对象的'any'类型报错
问题场景
给定如下对象和函数:
const obj = { user_name: 'user2', user_desc: 'desc 2', }; function myFunction(key_name: string) { console.log(obj[key_name]); }
代码运行正常,但TypeScript报错:Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'——原因是TypeScript无法确认传入的string类型参数是obj的有效键,因此无法推断索引后的类型。
解决方法
方法1:限定参数为对象的有效键(推荐)
使用keyof typeof obj将参数类型限定为obj的所有键名,既能保留类型安全,又能在编译期拦截无效键的调用:
const obj = { user_name: 'user2', user_desc: 'desc 2', }; // 参数类型限定为obj的键名 function myFunction(key_name: keyof typeof obj) { console.log(obj[key_name]); } // 合法调用 myFunction('user_name'); // 传入无效键会触发编译错误:Argument of type '"invalid_key"' is not assignable to parameter of type '"user_name" | "user_desc"' // myFunction('invalid_key');
方法2:为对象添加字符串索引签名
如果需要允许任意字符串作为键(比如动态生成键的场景),可以给对象定义字符串索引签名,放宽类型检查:
// 定义包含字符串索引的类型 type UserObj = { user_name: string; user_desc: string; [key: string]: string; // 表示任意字符串键对应的属性值都是string类型 }; const obj: UserObj = { user_name: 'user2', user_desc: 'desc 2', }; function myFunction(key_name: string) { console.log(obj[key_name]); }
注意:这种方式会丢失obj原有属性的精确类型约束,比如后续给obj添加非string类型的属性,TypeScript不会报错。
方法3:使用类型断言(简单但不安全)
通过类型断言强制告诉TypeScript传入的键是obj的有效键,这种方式不会改变参数类型,但编译期不会检查键的有效性,存在运行时风险:
const obj = { user_name: 'user2', user_desc: 'desc 2', }; function myFunction(key_name: string) { // 断言key_name是obj的有效键 console.log(obj[key_name as keyof typeof obj]); }
如果传入无效键,编译期不会报错,但运行时会得到undefined。
内容的提问来源于stack exchange,提问作者Wasiq Bin Zahid
相关产品推荐
相关产品推荐

