Typescript + React/Redux:类型“IntrinsicAttributes 和 IntrinsicClassAttributes”上不存在属性“XXX”

IT技术 reactjs typescript redux electron jsx
2021-04-19 06:26:42

我正在开发一个带有 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...'.

当我第一次遇到错误时,我认为这是因为我没有传入定义我的props的界面,但是我创建了它(如您所见),但它仍然不起作用。我想知道,有什么我想念的吗?

当我从 ContainerComponent 的代码中排除 ChildComponent props时,它呈现得很好(除了我的 ChildComponent 没有关键props)但在 JSX Typescript 中使用它拒绝编译它。我认为这可能与基于这篇文章的连接包装有关,但是那篇文章中的问题出现在 index.tsx 文件中,并且是提供程序的问题,我在其他地方遇到了我的问题。

4个回答

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

所以容器组件保持不变,但子组件发生了一些变化:

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);

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

注意:我知道这是一个非常简单的答案,我不确定为什么会这样,所以如果一个更有经验的 React ninja 想在这个答案上放下一些知识,我很乐意修改它。

2021-06-01 06:26:42
在搜索了这个问题很长时间后,我发现解决这个问题的关键在于对 的最终更改connect- 更新connect的界面以包含所提供的附加参数完全解决了该问题,不需要其他更改(至少对于我的代码)。
2021-06-11 06:26:42
但是React.Props已经弃用了!!
2021-06-19 06:26:42

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

前任。组件中提到的props类型必须与传递给该组件的props类型匹配。

让您的子组件使用您想要的类型或“任何”类型扩展 React.Component。例如:“ extends 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/了解更多信息

而不是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,
    };
})

在此处定义连接https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/typings/react-redux/react-redux.d.ts#L6-L36

为什么?

似乎您使用的定义可能已过时或无效(可能编写不当)。

看起来子组件上的连接肯定是问题所在,但我找到了一种解决问题的方法,而无需更改我使用的类型。使用此链接中的解决方案,我设法将连接更改为: connect<{}, {}, PassedProps> PassedProps 是组件从其父容器获取的道具。
2021-06-13 06:26:42