Angular使用*ngFor遍历对象时出现TypeScript类型错误:Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
我明白你遇到的问题了——即使加了*ngIf="myArticles.hasOwnProperty(key)",TypeScript还是不认可key是myArticles的有效属性,导致访问myArticles[key]时出现类型错误。这其实是TypeScript的类型推断机制导致的,咱们一步步来解决:
问题根源
当你用Object.keys(myArticles)获取对象键时,TypeScript默认会把它推断为string[]类型,而不是keyof typeof myArticles(也就是'hardware' | 'Software' | 'compsci')。虽然你用hasOwnProperty做了运行时检查,但TypeScript没办法从这个条件判断里自动缩小key的类型范围,所以它依然认为key可能是任意字符串,自然会质疑myArticles[key]的有效性。
解决方案:明确键的类型
我们需要给keys数组指定精确的类型,让TypeScript知道这些键都是myArticles的合法属性。
步骤1:定义类型别名
在组件的TypeScript代码里,先给articles的键定义一个类型:
type ArticleCategory = keyof typeof articles;
步骤2:给keys指定类型
把keys的类型声明为ArticleCategory[],同时用类型断言把Object.keys的结果转换为这个类型:
export class YourComponent { articles = { hardware: ['CPU', 'Motherboard', 'GPU', 'RAM', 'Power Supply'], Software: ['Operating System', 'Program', 'Web Site'], compsci: ['Algorithm', 'Programming', 'Data Structure'] }; // 这里指定精确类型 keys: ArticleCategory[] = Object.keys(this.articles) as ArticleCategory[]; }
步骤3:简化模板
现在TypeScript已经明确知道key是articles的合法键了,你甚至可以去掉模板里的*ngIf判断,代码会更简洁:
<h2>Browse through our articles:</h2> <section *ngFor="let key of keys"> {{key}} <div> <span *ngFor="let item of articles[key]"> <app-list-detail [list]="item"></app-list-detail> </span> </div> </section>
为什么原来的*ngIf没用?
hasOwnProperty的参数接受的是string类型,TypeScript无法通过这个运行时检查来推导key的具体类型——它没办法知道这个key一定是articles的键之一,所以类型错误依然存在。而通过明确keys的类型,我们从源头解决了类型推断的问题。
内容的提问来源于stack exchange,提问作者Epsilon-79

