Type escript + React/Redux: 属性“ XXX”不存在于类型“ IntrinsicAttritribute & IntrinsicClassAttritribute”上

我正在做一个项目,使用的是 Typescript,React 和 Redux (都是在 Electron 中运行的) ,当我将一个基于类的组件包含在另一个组件中并试图在它们之间传递参数时,我遇到了一个问题。宽泛地说,我为容器组件得到了以下结构:

class ContainerComponent extends React.Component<any,any> {
..
render() {
const { propToPass } = this.props;
...
<ChildComponent propToPass={propToPass} />
...
}
}


....
export default connect(mapStateToProps, mapDispatchToProps)(ContainerComponent);

而子女部分:

interface IChildComponentProps extends React.Props<any> {
propToPass: any
}


class ChildComponent extends React.Component<IChildComponentProps, any> {
...
}


....
export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);

显然,我只包含了基础知识,这两个类还有更多的内容,但是当我尝试运行我认为有效的代码时,仍然会得到一个错误。我得到的正是这个错误:

TS2339: Property 'propToPass' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState>> & Readonly<{ childr...'.

当我第一次遇到这个错误的时候,我认为这是因为我没有传入一个界面来定义我的道具,但是我创建了这个界面(正如你在上面看到的) ,它仍然不能工作。我在想,我是不是遗漏了什么?

当我从 ContainerComponent 的代码中排除 ChildComponent 道具时,它呈现得很好(除了我的 ChildComponent 没有一个关键道具之外) ,但是在 JSX Type 脚本中它拒绝编译它。我认为这可能与基于 这篇文章的连接包装有关,但是那篇文章中的问题出现在 index.tsx 文件中,是提供程序的问题,我正在其他地方解决这个问题。

143733 次浏览

不使用 export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);,而使用 connect装饰器 https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/app/fileTree.tsx#L136-L146

@connect((state: StoreState): Props => {
return {
filePaths: state.filePaths,
filePathsCompleted: state.filePathsCompleted,
rootDir: state.rootDir,
activeProjectFilePathTruthTable: state.activeProjectFilePathTruthTable,
fileTreeShown: state.fileTreeShown,
};
})

连接在哪里定义

为什么?

似乎您使用的定义可能已经过时或者无效(可能是编写得不好)。

因此,在阅读了一些相关的答案(特别是 这个这个,并查看了@basarat 对这个问题的答案后,我设法找到了一些对我有用的东西。它看起来(在我相对较新的 React 眼中)就像 Connect 没有为容器组件提供显式的接口,所以它被它试图通过的道具弄糊涂了。

因此容器组件保持不变,但子组件有所变化:

interface IChildComponentProps extends React.Props<any> {
... (other props needed by component)
}


interface PassedProps extends React.Props<any> {
propToPass: any
}


class ChildComponent extends React.Component<IChildComponentProps & PassedProps, any> {
...
}


....
export default connect<{}, {}, PassedProps>(mapStateToProps, mapDispatchToProps)    (ChildComponent);

以上的设法为我工作。显式传递组件期望从容器获得的道具似乎可以正常工作,并且两个组件都呈现得很好。

注意: 我知道这是一个非常简单的答案,而且我也不确定为什么这个有效,所以如果一个更有经验的反应忍者想要在这个答案上丢掉一些知识,我很乐意修改它。

仔细检查新添加的对象类型。当对象类型不完全符合预期时,将抛出此类错误。

组件中提到的道具类型必须与传递给该组件的道具类型相匹配。

使您的子组件扩展 React. Component,其类型为您想要的或“ any”类型

export class ChildComponent extends React.Component<T> {
render() {
return (
<button className="square">
{this.props.value}
</button>
);
}
}

然后在 Parent 组件中传递值,例如:

renderSquare(i: Number) { return <ChildComponent value={i}/>; }

查看 https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/class_components/了解更多信息

在我的例子中,我构建了一个类型脚本组件,它导入了 javascript 中使用 connect的组件。

这是我修复错误的一个快速方法。

// User is a javascript component
import _User from "./User";


// Inject types that this component accepts
const User = _User as unknown as React.JSXElementConstructor<{
userId: string
}>;


const UserProfile = () => {
const user = useCurrentUser();
return (
<div className="flex items-center justify-center">
<User userId={user.userId} />
</div>
);
}

希望这个能帮到你!

对我来说,有效的方法是将子组件类型从 React.FC 改为 JSX.Element

之前(警告)

const Component: React.FC = () => {


之后(没有警告)

const Component = (): JSX.Element => {