TypeScript使用string索引JSON对象报隐式any类型错误如何解决?
报错根本原因
TypeScript 默认导入 JSON 文件时,会基于 JSON 实际内容生成窄类型,当前示例中product.json的键被推断为"CT" | "CC"字面量联合类型。而你用来索引的codProduct.toUpperCase()是通用string类型,TS 无法确认这个字符串一定是 JSON 中存在的键,因此抛出类型报错。
解决方案
方案1:给JSON对象添加索引签名(最推荐,兼顾类型安全和灵活性)
给导入的product.json显式声明兼容string索引的类型即可,修改后完整代码如下:
import * as logger from 'winston'; import * as rawGetProperty from '../json/product.json'; import { ListProductBatchModel, ResultMsg } from '../models/listProduct.models'; // 定义JSON中商品项的结构类型 interface ProductItem { name: string; price: string; } // 给导入的JSON对象声明带string索引的类型,值可能为undefined(对应不存在的键) const getProperty = rawGetProperty as Record<string, ProductItem | undefined>; export class ListProductBatchUtils { public async getDataProduct(codProduct: string): Promise<ListProductBatchModel> { try { let result: ResultMsg; // 提前存变量避免重复索引取值,优化代码简洁度 const productKey = codProduct.toUpperCase(); const targetProduct = getProperty[productKey]; if (targetProduct) { result = { name: targetProduct.name, price: targetProduct.price } }else { result = { error: "ERROR" } } logger.info('start') return Promise.resolve({ resp: result }); } catch (error) { logger.info(JSON.stringify(error)); return Promise.reject(error); } } }
该方案既保留了商品项内部name、price字段的类型校验,也允许用任意字符串索引,同时返回值自动标记为可能为undefined,刚好适配你现有的非空判断逻辑。
方案2:收窄入参类型(适合JSON键固定不变的场景)
如果你的product.json后续不会新增商品键,可以直接把入参类型限定为已有的键的联合:
// 仅修改入参类型即可,其余逻辑不变 public async getDataProduct(codProduct: 'CT'|'CC'): Promise<ListProductBatchModel> { // ... }
该方案类型校验最严格,但灵活性差,后续JSON新增键需要同步修改入参类型定义。
方案3:临时关闭类型校验(不推荐,仅做快速修复用)
如果只是需要临时跳过报错,可以加any断言:
// 索引时添加as any断言 if ((getProperty as any)[codProduct.toUpperCase()]) { name: (getProperty as any)[codProduct.toUpperCase()].name, }
内容的提问来源于stack exchange,提问作者menphis
相关产品推荐
相关产品推荐

