React/Typscript: typehint any 不起作用
React/Typscript: typehint any doesn't work
我有一个非常简单的反应组件,名为: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[]'.
我得到上述错误 4 次,for user.login
, user.public_repos
, user.followers
, user.avatar_url
"Typehint" in React.Component<{any, any}>
与状态类型无关,这是您指定的道具类型。查看 React 组件的声明:declare class React$Component<Props, State = void> { ...
创建组件时,传递给 React.Component
的第一个类型是 props 类型,而第二个类型定义状态类型:
interface IState {}
interface IProps {}
class Component extends React.Component<IProps, IState> {
当你这样做时:
class Github extends React.Component<{any, any}>
您只是将组件道具类型定义为一个对象,该对象具有两个都称为 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,
});
}
...
}
你犯了语义错误。虽然您的程序在语法上是有效的,但这并不意味着您的意图。
关键在于,在 TypeScript 中,声明的形式为
<name> [: type]
也就是说,名称首先出现并且是必需的,并且始终是必需的,并且如果需要,可以在其后跟一个类型注释。
因此,如果我写,
type Props = {
any
};
我正在声明一个名为 any
的 属性 类型。以上相当于
type Props = {
any: any
};
因为我没有类型注释,也没有推断它的上下文。
此外,我写,
type Props = {
any,
any
};
我声明了一个名为 any
的成员两次,一个错误。
您可能打算像这样为 Props
和 State
类型参数指定类型 any
。
class Github extends React.Component<any, any> {
}
但是您为 Props
指定了类型 {any, any}
,而没有为 State
指定类型。
有多种原因:
React.Component
接口接受两种类型,React.Component<P, S>
其中 P 是 props 的类型,S 是状态的类型。它还可以接受一个类型,它只是 P。这就是你的情况,你将类型 P 定义为对象 {any, any}
(打字稿应该抱怨它,因为你指定了重复的键)。这意味着您根本没有为国家提供类型。其中来自 DefinetelyTyped should be any。
您在 class 上明确定义了 state
,因此打字稿从定义中推迟了它的类型。 state.user
是一个数组,所以这个元素上没有avatar_url
;
要解决此问题,您可以尝试在定义
时明确说明 state
是任意的
state: any = {
user: []
}
更好的解决方案是实际为状态定义类型或接口,而不使用任何类型或接口。 any
应该避免,尤其是在您为应用程序编写的代码中。
您可以定义用户类型或界面:
type User = {
name: string,
avatar?: string
}
// or
interface IUser {
name: string,
avatar?: string
}
我有一个非常简单的反应组件,名为: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[]'.
我得到上述错误 4 次,for user.login
, user.public_repos
, user.followers
, user.avatar_url
"Typehint" in React.Component<{any, any}>
与状态类型无关,这是您指定的道具类型。查看 React 组件的声明:declare class React$Component<Props, State = void> { ...
创建组件时,传递给 React.Component
的第一个类型是 props 类型,而第二个类型定义状态类型:
interface IState {}
interface IProps {}
class Component extends React.Component<IProps, IState> {
当你这样做时:
class Github extends React.Component<{any, any}>
您只是将组件道具类型定义为一个对象,该对象具有两个都称为 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,
});
}
...
}
你犯了语义错误。虽然您的程序在语法上是有效的,但这并不意味着您的意图。
关键在于,在 TypeScript 中,声明的形式为
<name> [: type]
也就是说,名称首先出现并且是必需的,并且始终是必需的,并且如果需要,可以在其后跟一个类型注释。
因此,如果我写,
type Props = {
any
};
我正在声明一个名为 any
的 属性 类型。以上相当于
type Props = {
any: any
};
因为我没有类型注释,也没有推断它的上下文。
此外,我写,
type Props = {
any,
any
};
我声明了一个名为 any
的成员两次,一个错误。
您可能打算像这样为 Props
和 State
类型参数指定类型 any
。
class Github extends React.Component<any, any> {
}
但是您为 Props
指定了类型 {any, any}
,而没有为 State
指定类型。
有多种原因:
React.Component
接口接受两种类型,React.Component<P, S>
其中 P 是 props 的类型,S 是状态的类型。它还可以接受一个类型,它只是 P。这就是你的情况,你将类型 P 定义为对象{any, any}
(打字稿应该抱怨它,因为你指定了重复的键)。这意味着您根本没有为国家提供类型。其中来自 DefinetelyTyped should be any。您在 class 上明确定义了
state
,因此打字稿从定义中推迟了它的类型。state.user
是一个数组,所以这个元素上没有avatar_url
;
要解决此问题,您可以尝试在定义
时明确说明state
是任意的
state: any = {
user: []
}
更好的解决方案是实际为状态定义类型或接口,而不使用任何类型或接口。 any
应该避免,尤其是在您为应用程序编写的代码中。
您可以定义用户类型或界面:
type User = {
name: string,
avatar?: string
}
// or
interface IUser {
name: string,
avatar?: string
}