在这个简单的组件中,我传入了如下所示的MyProps:
interface MyProps {
profiles: IProfile[]
}
interface IProfile {
name: string;
avatar_url: string;
company: string;
}
我的组件将props定义为MyProp
,但是Typescript编译器抱怨this.state.profiles does not exist on type Readonly<{}>
:
class App extends React.Component<MyProps> {
constructor(props: MyProps) {
super(props);
this.state = { profiles: props.profiles };
}
public render() {
return (<div>//ERROR HERE
{this.state.profiles.map((profile: IProfile) => <Card {...profile} />)}
</div>);
}
};
如果我将第二个字段设置为any或MyProps,它将起作用。我是否总是需要定义React.Component的前两个参数?
class App extends React.Component<MyProps,MyProps>
答案 0 :(得分:2)
在TypeScript中,
React.Component
是通用类型(又名
React.Component<PropType, StateType>
)
由于要在该组件中定义状态,因此需要为状态创建一个接口以进行类型检查。
interface MyState {
profiles: IProfile[];
}
创建完之后,可以将其提供给React.Component
class App extends React.Component<MyProps, MyState> {
constructor(props: MyProps) {
super(props);
this.state = { profiles: props.profiles };
}
public render() {
return (<div>//ERROR HERE
{this.state.profiles.map((profile: IProfile) => <Card {...profile} />)}
</div>);
}
};
答案 1 :(得分:1)
我只想稍微扩展一下已经提供的答案。
直到最近,您始终必须将Props类型和State类型都提供给Component<P,S>
泛型类型,因此class App extends React.Component<MyProps>
一直是一个错误,说您需要为State提供一个类型
现在,Typescript支持默认的通用类型,而React类型通过定义以下内容来使用它:
interface Component<P = {}, S = {}, SS = any> extends ComponentLifecycle<P, S, SS> { }
这意味着您不再需要始终为道具和州提供类型,并且如果您不提供道具和州的类型,则它们将默认为{{ 1}},这是一个没有属性的对象。由于类型{}
上不存在属性profiles
,因此您将看到所观察到的类型错误。
我之所以提出这种区分,是因为您对问题的实际答案是“否”,因为通用类型默认设置,您不是总是需要定义{}
的前两个参数。但是,如果不提供它们,它们将默认为类型React.Component
,该类型没有属性。因此,如果要在组件内部使用Props和State,则必须提供Props and State类型。