我有一个非常简单的react组件,名为:github.tsx
其中有以下代码:
import React from 'react'
import axios from 'axios'
class Github extends React.Component<{any, any}>{
state = {
user: []
}
getRepoUser = async () => {
let res = await axios.get('https://api.github.com/users/example');
this.setState({
user: res.data
})
}
componentDidMount () {
this.getRepoUser()
}
render () {
const { user } = this.state
return (
<div>
<h2>{user.login}</h2>
<p> repos: {user.public_repos} </p>
<p>followers: {user.followers}</p>
<img src={user.avatar_url} alt=""/>
</div>
)
}
}
export default Github
我认为通过向组件中添加<{any, any}>
,我不会有任何问题,但是会看到类似以下的控制台错误:
backend.js:6 /home/example/tuts/components/github.tsx
./components/github.tsx
[tsl] ERROR in /home/example/tuts/components/github.tsx(35,24)
TS2339: Property 'avatar_url' does not exist on type 'any[]'.
对于user.login
,user.public_repos
,user.followers
,user.avatar_url
,我收到4次以上错误
答案 0 :(得分:1)
创建组件时,传递给React.Component
的第一种类型是props类型,而第二种定义状态类型:
interface IState {}
interface IProps {}
class Component extends React.Component<IProps, IState> {
执行此操作时:
class Github extends React.Component<{any, any}>
您仅将组件props类型定义为具有两个都称为any
的属性的对象,这将不起作用。
您的组件键入应改为:
class Github extends React.Component<any, any>
state.user
的推断类型也是一个数组,因为初始状态是:
state = {
user: []
}
这就是为什么您会收到有关user.login
,user.public_repos
...
您可以这样输入状态:
interface IState {
user: User;
}
interface User {
login: string;
public_repos: string;
followers: string;
avatar_url: string;
}
class Github extends React.Component<any, IState> {
public state = {
user: {
login: "",
public_repos: "",
followers: "",
avatar_url: "",
},
};
public getRepoUser = async () => {
const res = await axios.get<User>("https://api.github.com/users/example");
this.setState({
user: res.data,
});
}
...
}
答案 1 :(得分:1)
您正在犯语义错误。尽管您的程序在语法上是有效的,但这并不意味着您打算执行什么。
关键点在于,在TypeScript中,声明的形式为
<name> [: type]
也就是说,名字是第一位的,并且总是必需的,如果需要,可以在其后加上类型注释。
因此,如果我写信,
type Props = {
any
};
我正在声明一个名为any
的属性类型。以上等同于
type Props = {
any: any
};
因为我没有类型注释,也没有上下文可以推断出来。
此外,我写道,
type Props = {
any,
any
};
我两次声明了一个名为any
的成员,这是一个错误。
您可能希望为any
和Props
类型的参数都指定类型State
。
class Github extends React.Component<any, any> {
}
但是您改为为{any, any}
指定类型Props
,而没有为State
指定类型。
答案 2 :(得分:1)
有多种原因:
React.Component
接口接受两种类型,React.Component<P, S>
,其中P是道具的类型,S是状态的类型。它也可以接受单个类型,即P。这就是您所遇到的情况,您正在将类型P定义为对象{any, any}
(打字稿应该抱怨它,因为您指定了重复键)。这意味着您根本不提供国家的类型。来自DefinetelyTyped should be any。
您是在类上显式定义state
,因此打字稿会从定义中推迟其类型。 state.user
是一个数组,因此该元素上没有avatar_url
;
要解决此问题,您可以尝试明确声明state
在定义时为
state: any = {
user: []
}
更好的解决方案是实际为状态定义类型或接口,而不使用任何状态。应该避免使用any
,尤其是在为应用程序编写的代码中。
您可以定义用户喜欢的类型或界面:
type User = {
name: string,
avatar?: string
}
// or
interface IUser {
name: string,
avatar?: string
}
答案 3 :(得分:0)
React.Component<{any, any}>
中的“ Typehint”与状态类型无关,这是您指定的道具类型。检出react组件的声明:declare class React$Component<Props, State = void> { ...