React+TypeScript报错:Property 'album'不存在于类型'never[]'
嘿,我来帮你梳理下你遇到的几个问题,都是React+TypeScript新手常踩的小坑,咱们一步步解决:
1. never[]类型错误:TypeScript的类型推断坑
你已经在State接口里明确定义了gallery: Album[],但初始化state时直接给了空数组[]——TypeScript会默认把这个空数组推断为never[](因为它不知道数组里应该装什么类型),这就导致后续访问gallery的属性时触发类型错误。
解决方法很简单,给state显式指定类型就行:
class App extends React.Component<{}, State> { // 这里明确标注state的类型为你定义的State接口 state: State = { isLoading: false, errorMsg: '', buttonClicked: false, jsonFromServer: "", gallery: [] // 现在TypeScript会知道这是Album[]类型的空数组 } // ...其他代码 }
或者也可以给空数组加类型断言[] as Album[],不过直接给state整体指定类型更规范。
2. 致命笔误:galerie≠gallery
在render方法里你写了this.state.galerie.length > 0,这里的拼写错了!应该是this.state.gallery。这个笔误会导致你的条件判断永远不成立,还会触发额外的类型错误(因为galerie根本不是state的属性)。
3. 数组与单个对象的访问混淆
你的gallery是Album数组(Album[]),但你却尝试写this.state.gallery.album.id——这里有两个明显问题:
- 数组本身没有
album属性,你得先访问数组里的具体元素,比如gallery[0](前提是数组不为空) - 你定义的
Album类型里根本没有album这个字段,Album本身就有id、name等属性,所以正确的访问应该是this.state.gallery[0].id
另外还要注意:如果服务器返回的result.data.gallery其实是单个Album对象(不是数组),那你需要把State里的gallery改成Album | null,初始化值设为null,避免类型不匹配。
修正后的核心代码示例
import React, { Component } from 'react'; import axios from 'axios'; const API = 'http://www.mydomain/testapi/'; const DEFAULT_QUERY = 'test.php'; type Image = { id: number, name: string, title: string, date: string, size: number } type Album = { id: number, name: string, path: string, images: Image[] } interface State { jsonFromServer: string, isLoading: boolean, errorMsg: string, buttonClicked: boolean, gallery: Album[] } class App extends React.Component<{}, State> { state: State = { isLoading: false, errorMsg: '', buttonClicked: false, jsonFromServer: "", gallery: [] } getInfo() { this.setState({ isLoading: true, buttonClicked: true }); axios.get(API + DEFAULT_QUERY) .then(result => this.setState({ gallery: result.data.gallery, isLoading: false, jsonFromServer: JSON.stringify(result.data) // 这里注意:result.data是对象,不能直接赋值给string类型的jsonFromServer,得转成字符串! })) .catch(error => this.setState({ errorMsg: error.message, isLoading: false })); } render() { // ...你的其他渲染代码 if (this.state.buttonClicked) { if (this.state.gallery.length > 0) { // 访问第一个Album的id console.log('=>', this.state.gallery[0].id); // 如果要遍历所有Album this.state.gallery.forEach(album => { console.log('Album ID:', album.id); console.log('Album Name:', album.name); }); } } // ...你的其他渲染代码 return <div>{/* 你的组件内容 */}</div>; } } export default App;
哦对了,还有个隐藏的小问题:你的jsonFromServer是string类型,但你直接把result.data(对象)赋值给它,这也会触发类型错误,得改成JSON.stringify(result.data)把对象转成字符串才行。
总结一下,你主要遇到了类型推断的小坑、笔误、数组访问逻辑错误,还有一个隐藏的类型不匹配问题,按照上面的修正应该就能全部解决啦!
内容的提问来源于stack exchange,提问作者jurilitvin

