通过 React 高阶组件传递子道具的正确 TypeScript 类型
Posted
技术标签:
【中文标题】通过 React 高阶组件传递子道具的正确 TypeScript 类型【英文标题】:Correct TypeScript types for passing children props through a React higher order component 【发布时间】:2021-11-23 15:02:51 【问题描述】:考虑以下代码,其中包含一个高阶组件、一个函数式组件以及一个使用 HOC 和我们的函数式组件创建的组件:
interface InjectedProps
someProp?: number;
const myHoc = <P extends >(
Component: ComponentType<P>
) => (someProp, ...props: P & InjectedProps) =>
return <Component ...props as P />;
const MyComponent = (props: children?: React.ReactNode) =>
return <div>props.children</div>;
;
const WrappedComponent = myHoc(MyComponent);
但是,当我们尝试使用这个新的WrappedComponent
:
return (
<WrappedComponent>
<h1>Hello</h1>
<h2>World</h2>
</WrappedComponent>
);
我们最终得到错误:Type ' children: Element[]; ' has no properties in common with type 'IntrinsicAttributes & InjectedProps'.
。
这可以通过将children
props 注入到 HOC 的 props 中来解决,像这样;
interface InjectedProps
someProp?: number;
children?: React.ReactNode;
然而,我们现在遇到的问题是所有包装的组件现在都可以接收子组件,即使它们以前不能。
我的问题是,对于将子组件传递到包装组件中的高阶组件,正确的类型是什么?
【问题讨论】:
【参考方案1】:你看到这个错误是因为P extends
,而它应该扩展P extends children?: React.ReactNode;
,因为你想提供children
。
顺便说一句,仅使用空对象 作为通用约束被认为是一种不好的做法。您应该使用
Record<PropertyKey, unknown>
而不是。
此外,您应该使用ComponentType<Omit<P & InjectedProps, "someProp">>
而不是ComponentType<P>
,因为这是 TS 推断此类型的方式。
工作代码:
import React, FC, ComponentType from 'react'
interface InjectedProps
someProp?: number;
type WithChildren =
children?: React.ReactNode;
const myHoc = <P extends WithChildren>(
Component: ComponentType<Omit<P & InjectedProps, "someProp">>
) => ( someProp, ...props : P & InjectedProps) => <Component ...props />
const MyComponent: FC = (props) => <div>props.children</div>
const WrappedComponent = myHoc(MyComponent);
const App = () => (
<WrappedComponent>
<h1>Hello</h1>
<h2>World</h2>
</WrappedComponent>
)
Playground
【讨论】:
以上是关于通过 React 高阶组件传递子道具的正确 TypeScript 类型的主要内容,如果未能解决你的问题,请参考以下文章
在 react-router v4 中将自定义道具传递给路由器组件