Typescript + React / Redux:Property" XXX"类型' IntrinsicAttributes& IntrinsicClassAttributes

时间:2017-03-07 20:32:54

标签: reactjs typescript redux electron jsx

我正在使用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 prop时,它渲染得很好(除了我的ChildComponent没有关键道具)但是在JSX Typescript中拒绝编译它。我认为它可能与基于this article的连接包装有关,但该文章中的问题发生在index.tsx文件中并且是提供者的问题,我遇到了问题别处。

4 个答案:

答案 0 :(得分:37)

因此,在阅读了一些相关答案(特别是this onethis one并查看@ 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忍者想要放弃一些关于这个答案的知识我&# 39;我乐意修改它。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

让您的子组件使用您想要的类型或“任何”类型扩展 React.Component。例如:“extends React.Component<any> {...}

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

在父组件中,您可以传递值,例如:

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

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

答案 3 :(得分:-3)

而不是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

为什么?

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