创建一个返回反应组件类的打字稿函数
Posted
技术标签:
【中文标题】创建一个返回反应组件类的打字稿函数【英文标题】: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 <div><GenericEditor /></div>
当函数返回一些组件(不是实例)时,最好使用更通用的React.ComponentType
- function getFooClass(condition: boolean): React.ComponentType
AlekseyL.,另一个假设,我的问题是由 @types/react 中的错误引起的。您在 Playground 的示例中使用了 react 16,而我的项目对应的是旧的 react 版本 15 和旧的 @types 包。
【参考方案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;
【讨论】:
这不会编译,应该使用React.ComponentType
。但即使使用React.ComponentType
,new SomeFooClass()
也不会被允许
对不起.. 我现在明白了:/
@AlekseyL。使用 React.ReactNode 将编译
答案已更新 - 这是反应 TS 事物的绝佳资源github.com/typescript-cheatsheets/react-typescript-cheatsheet
现在完全错了,React.ReactNode
是渲染的结果,而不是组件的类型github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/…以上是关于创建一个返回反应组件类的打字稿函数的主要内容,如果未能解决你的问题,请参考以下文章
使用打字稿创建自定义反应路由组件。类型上不存在属性“路径”... RouteProps