【问题标题】:Create a typescript function returning react component class创建一个返回反应组件类的打字稿函数
【发布时间】:2020-06-03 19:17:55
【问题描述】:

我需要创建一个实用函数,它将根据某些条件返回一个反应组件类(而不是实例)。所以函数的返回类型应该是泛型的(React.PureComponent)

import React from 'react';
class FooOne extends React.PureComponent {
    render(): React.ReactElement {
        return null;
    }
}
class FooTwo extends React.PureComponent {
    render(): React.ReactElement {
        return null;
    }
}
function getFooClass(condition: boolean): typeof React.PureComponent {
    return condition ? FooOne : FooTwo;
}
const SomeFooClass = getFooClass(true);
const instance: React.PureComponent = new SomeFooClass();

上面的代码倾向于工作(我仍然不明白为什么我需要使用 typeof React.PureComponent 作为 getFooClass 的返回类型,这是通过实验发现的), 但是 typescript 会为 getFooClass 生成以下错误:

Type 'typeof FooOne' is not assignable to type 'typeof PureComponent'.
  Construct signature return types 'FooOne' and 'PureComponent<P, S>' are incompatible.
    The types of 'props' are incompatible between these types.
      Type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>' is not assignable to type 'Readonly<{ children?: ReactNode; }> & Readonly<P>'.
        Type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>' is not assignable to type 'Readonly<P>'.

也许这是一种打字稿错误或限制?

【问题讨论】:

  • 您使用的是哪个版本的打字稿? This works...
  • 关于typeof - 需要表明您正在返回构造函数而不是实例。顺便说一句,为什么需要使用new SomeFooClass.. 手动实例化组件?只是好奇
  • @AlekseyL.,新的 SomeFooClass 看起来真的很奇怪,这实际上是个坏例子。它是如何使用的:class AnotherComponent extends Component { const GenericEditor = getFooClass(this.state.condition); render() { return &lt;div&gt;&lt;GenericEditor /&gt;&lt;/div&gt; } }
  • 当函数返回一些组件(不是实例)时,最好使用更通用的React.ComponentType - function getFooClass(condition: boolean): React.ComponentType
  • AlekseyL.,另一个假设,我的问题是由 @types/react 中的错误引起的。您在 Playground 的示例中使用了 react 16,而我的项目对应的是旧的 react 版本 15 和旧的 @types 包。

标签: reactjs typescript


【解决方案1】:

试试类似的东西

function getFooClass(condition: boolean): React.ComponentType {
   // if FooOne and FooTwo have arguments you can use React.ComponentType<TArgs>
   return condition ? FooOne : FooTwo;
}

用法应该是这样的

function render() {
    const FooEl = getFooClass(true); // PascalCase is required
    return <FooEl />
}

或者直接返回创建的实例

function getFooClass(condition: boolean): JSX.Element  {
   return condition ? <FooOne /> : <FooTwo />;
}

【讨论】:

    【解决方案2】:

    React.ReactNode 在这种情况下应该可以工作:

    function getFooClass(condition: boolean): React.ReactNode {
      return condition ? FooOne : FooTwo;
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2021-04-10
    • 2018-03-20
    • 2021-09-17
    • 2022-01-12
    • 2015-08-10
    • 2019-09-26
    相关资源
    最近更新 更多