javascript - 如何在 Typescript 中为其子级设置函数 props 类型?类型 TS2339 上不存在属性 'children'

标签 javascript reactjs typescript

作为引用,我使用的是 React 16.9.0 和 Typescript 3.5.3。如果您安装 Create React App 并创建 Typescript 项目,则可以添加以下最小示例来重现问题:

import React from 'react';
import './App.css';

interface TreeComponentProps {
  recursion_level: number;
}

interface TreeComponentState {
}

class TreeComponent extends React.Component<TreeComponentProps, TreeComponentState>
{
  constructor(props: TreeComponentProps) {
    super(props);
    this.state = {
    };
  }

  render() {
    console.log( 'I was triggered during TreeComponent render...' );

    // const ListElements: any = (props: any) =>
    const ListElements: React.FunctionComponent<TreeComponentProps> = (props: TreeComponentProps) =>
    {
      if( props.recursion_level > 1 )
      {
        return (
          <ol>
            {props.children}
          </ol>
        );
      }
      else {
        return (
          <React.Fragment>
            {props.children}
          </React.Fragment>
        );
      }
    }

    if( this.props.recursion_level > 3 ) {
      return <div> End recursion on {this.props.recursion_level}... </div>
    }

    return (
      <ListElements>
        <div> recursion_level {this.props.recursion_level + 1} <br /> </div>
        <TreeComponent key={0} recursion_level={ this.props.recursion_level + 1 }/>
      </ListElements>
    )
  }
}

interface AppProps {
}

interface AppState {
}

class App extends React.Component<AppProps, AppState>
{
  private recursion_level: number;

  constructor(props: AppProps) {
    super(props);

    this.recursion_level = 0;
    this.state = {
    };
  }

  render() {
    console.log( 'I was triggered during App render:', this.state )

    return (
        <TreeComponent key={0} recursion_level={ this.recursion_level }/>
    )
  }
}

export default App;

-->

Property 'children' does not exist on type 'TreeComponentProps'.  TS2339

    27 |         return (
    28 |           <ol>
  > 29 |             {props.children}
       |                    ^
    30 |           </ol>
    31 |         );
    32 |       }

如果我更换线路:

const ListElements: React.FunctionComponent<TreeComponentProps> = (props: TreeComponentProps) =>
// -->
const ListElements: any = (props: any) =>

然后,一切正常,页面正确生成:

recursion_level 1
recursion_level 2
recursion_level 3
recursion_level 4
End recursion on 4...

我已经研究过这个问题How to use children with React Stateless Functional Component in TypeScript?这是正确的语法:

Since React 16.8, the names React.SFC and React.StatelessComponent are depricated. Actually, they have become aliases for React.FunctionComponent type or React.FC for short.

You would use them the same way though:

const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

如何正确设置 typescript 的内部函数 Prop 类型,而不必在任何地方继续使用任何 Prop ?

最佳答案

您不需要显式声明 MyStatelessComponent 的类型,因为它可以被推断出来。

此外,由于您在第二个 TreeComponent 声明中没有使用 children,因此您需要将 children 标记为可选以删除类型错误。

您还缺少 ListElements 组件的 recursion_level={this.props.recursion_level} 属性

import React from 'react';
import './App.css';

interface TreeComponentProps {
  recursion_level: number;
  children?:React.ReactNode
}

interface TreeComponentState {
}

class TreeComponent extends React.Component<TreeComponentProps, TreeComponentState>
{
  constructor(props: TreeComponentProps) {
    super(props);
    this.state = {
    };
  }

  render() {
    console.log( 'I was triggered during TreeComponent render...' );

    // const ListElements: any = (props: any) =>
    const ListElements = (props: TreeComponentProps) =>
    {
      if( props.recursion_level > 1 )
      {
        return (
          <ol>
            {props.children}
          </ol>
        );
      }
      else {
        return (
          <React.Fragment>
            {props.children}
          </React.Fragment>
        );
      }
    }

    if( this.props.recursion_level > 3 ) {
      return <div> End recursion on {this.props.recursion_level}... </div>
    }

    return (
      <ListElements recursion_level={this.props.recursion_level}>
        <div> recursion_level {this.props.recursion_level + 1} <br /> </div>
        <TreeComponent key={0} recursion_level={ this.props.recursion_level + 1 }/>
      </ListElements>
    )
  }
}

interface AppProps {
}

interface AppState {
}

class App extends React.Component<AppProps, AppState>
{
  private recursion_level: number;

  constructor(props: AppProps) {
    super(props);

    this.recursion_level = 0;
    this.state = {
    };
  }

  render() {
    console.log( 'I was triggered during App render:', this.state )

    return (
        <TreeComponent key={0} recursion_level={ this.recursion_level }/>
    )
  }
}

export default App;

关于javascript - 如何在 Typescript 中为其子级设置函数 props 类型?类型 TS2339 上不存在属性 'children',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57930785/

相关文章:

javascript - Interact.js 可调整大小和可拖动不能一起工作

javascript - currentStyle 与 getComputedStyle 的 Firefox 问题

javascript - 如果用户调整页面大小,则更改页面的 JavaScript 代码

reactjs - React-boilerplate+grommet,使 sass 与 webpack 一起工作

typescript - 如何在 Typescript 中编写严格要求其参数的函数类型

javascript - Framer Motion "repeatType"属性导致类型错误

javascript - jQuery 在控制台中工作但不在网站中工作。我也在使用 AngularJS

javascript - 动态改变 react 模态内容

javascript - 使用 NextJS 将 SASS 变量导入 Material UI 主题

html - Angular 2 routerLink 不起作用