Angular中如何从Model获取JSON数据 动态属性名访问失效如何解决
问题描述
从Model中获取JSON数据时,直接使用
this.products.allproduct['product1']可以正常取值,但使用动态变量作为索引this.products.allproduct[prd]语法无法生效。
相关代码
- app.component.html
<button (click)="getData('product1')">Product 1</button> <button (click)="getData('product2')">Product 2</button> <button (click)="getData('product3')">Product 3</button> <div> {{showData}} </div>
- app.component.ts
getData(prd: string|number) { this.showData = this.products.allproduct[prd]; }
问题原因
本质是TypeScript的严格类型校验规则触发的报错:allproduct对象默认没有声明可索引的类型签名,当你使用动态变量作为索引时,TypeScript无法提前确认该变量的值是allproduct上存在的合法键,因此会抛出类型错误。直接写死字符串索引不报错,是因为TypeScript可以直接识别到该字符串是allproduct上已有的属性,类型自动匹配通过。
解决方案
按推荐优先级排序可选以下三种方案:
方案1:为对象声明可索引类型(最推荐,类型安全)
在定义products对应的数据类型时,为allproduct字段声明可索引的类型签名,明确该对象可以用字符串作为键取值:
// 先定义单个产品的字段类型,根据实际业务调整 interface ProductItem { name: string; price: number; // 其他产品属性 } // 声明allproduct的类型:支持字符串索引,值为ProductItem类型 interface AllProductMap { [key: string]: ProductItem } // 为你的products变量绑定类型 products: { allproduct: AllProductMap }
修改完成后原getData方法不需要改动即可正常运行。
方案2:使用类型断言临时跳过校验(适合临时快速修复)
如果不想修改全局类型定义,可以在取值时添加类型断言,告知TypeScript该索引是合法值:
getData(prd: string|number) { // 写法1:将prd断言为allproduct的合法键 this.showData = this.products.allproduct[prd as keyof typeof this.products.allproduct]; // 写法2:将allproduct断言为可任意索引的对象 // this.showData = (this.products.allproduct as {[key:string]:any})[prd]; }
方案3:收窄参数类型为字面量联合(适合键值固定的场景)
如果你的产品键只有固定的product1/product2/product3三个值,可以直接将参数类型定义为这三个值的联合类型,从源头保证参数合法性:
// 参数只能是三个合法键中的一个 getData(prd: 'product1' | 'product2' | 'product3') { this.showData = this.products.allproduct[prd]; }
内容的提问来源于stack exchange,提问作者Sansara
相关产品推荐
相关产品推荐

