【问题标题】:React.PropsWithChildren with no props other than `children`?React.PropsWithChildren 除了`children` 没有其他道具?
【发布时间】:2021-01-03 09:40:39
【问题描述】:

我有一个组件除了children 之外没有任何道具,即:

function Foo({ children }: React.PropsWithChildren<>) {}

React.PropsWithChildren 需要一个参数。如果我做React.PropsWithChildren&lt;{}&gt;,Eslint 会产生Don't use `{}` as a type. `{}` actually means "any non-nullish value".

我将它用于空对象类型:

type EmptyObj = { [k: string]: never };

但是,React.PropsWithChildren&lt;EmptyObj&gt; 导致:

Type '{ children: Element; }' is not assignable to type 'EmptyObj'.
  Property 'children' is incompatible with index signature.
    Type 'Element' is not assignable to type 'never'.

我应该将什么传递给React.PropsWithChildren

编辑:

我知道我能做到:

function Foo({ children }: { children?: React.ReactNode }) {}

但是,我在整个代码库中都使用React.PropsWithChildren,所以我希望保持一致。

【问题讨论】:

  • 你能重新创建类型错误吗?您配置了一些不常见的规则,即使 obj 为空,我也没有收到任何警告:codesandbox.io/s/hungry-benz-35y0l?file=/src/App.tsx:0-220
  • 我忘了说我正在使用typescript-eslint
  • 另外,您也可以禁用 eslint 规则。总是让我感到惊讶的是,人们有时会跳过去让 eslint 开心。 Eslint 应该让你的代码更好。如果您认为某条规则不适用,请不要使用该规则
  • 这是一条有用的规则,令人沮丧的是打字稿
  • 我会以牺牲清晰度为代价来争论一致性是没有意义的。就像,如果有一个更简单的方法(你引用它)为什么不直接使用它呢?相反,您会遇到 ESLint 警告,因为该类型没有意义,并且您使用更复杂的东西“解决它”(接受的答案)。如果你真的嫁给了React.PropsWithChildren&lt;{}&gt;,为什么不直接用comment-pragma 让ESLint 警告静音呢?完全理解想要知道如何去做的愿望,但随后真正去做......不计算。

标签: javascript reactjs typescript


【解决方案1】:

解决办法是:

function Foo({ children }: React.PropsWithChildren<Record<never, any>>) {}

如果 eslint 警告您输入 any,请改用 Record&lt;never, never&gt;

【讨论】:

    【解决方案2】:

    您可以使用FC 类型,如下所示:

    const Foo: FC = ({ children }) => {
        return <div>{children}</div>;
    };
    

    如果你真的想坚持PropsWithChildren,那么使用PropsWithChildren&lt;unknown&gt; 而不是PropsWithChildren&lt;{}&gt;。您收到的警告来自typescript-eslint,并且可以作为另一种选择关闭这些情况。

    【讨论】:

      【解决方案3】:

      我也遇到了同样的情况,决定选择:

      PropsWithChildren<unknown>
      

      我们声明了一个接受子组件的组件,但我们不知道(或不关心)它可能拥有的其他道具。

      示例:

      const MyComponent = ({ children }: PropsWithChildren<unknown>) => { /* ... */ }
      
      // ...
      
      <MyComponent>
        <span>children</span>
      </MyComponent>
      

      为什么不用 FC 类型?

      不鼓励使用FC 类型。您可以在此 PR 中了解更多信息:https://github.com/facebook/create-react-app/pull/8177

      【讨论】:

        【解决方案4】:

        看看React.FC&lt;&gt;是怎么实现的可以试试:

        interface WrapperProps<> {}
        
        function App(props: React.PropsWithChildren<WrapperProps>) {
          return <div>{props.children}...</div>;
        }
        

        【讨论】:

        • eslint@typescript-eslint/no-empty-interface 出现错误“空接口相当于{}
        【解决方案5】:

        您知道并定义了 FC 将接收的儿童类型吗?如果是这样,你能不能只拥有一个作为子属性值传入的联合类型?

        type FooChildren = ChildTypeOne | ChildTypeTwo | ChildTypeThree;
        type FooProps = { children?: FooChildren[] };
        
        function Foo({ children }: React.PropsWithChildren<FooProps>) {}
        

        另外,ReactChildren 本身不是一个接口吗?为什么不在函数参数中使用它?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-20
          • 2019-01-04
          • 2017-11-27
          • 2021-12-27
          • 2019-05-12
          • 2014-01-10
          相关资源
          最近更新 更多