使用 TypeScript 编写 React 高阶组件

2024-01-24

我正在写一个反应高阶组件(HOC) https://facebook.github.io/react/docs/higher-order-components.html使用 TypeScript。 HOC 应该比包装组件多接受一个 prop,所以我这样写:

type HocProps {
    // Contains the prop my HOC needs
    thingy: number
}
type Component<P> = React.ComponentClass<P> | React.StatelessComponent<P>
interface ComponentDecorator<TChildProps> {
    (component: Component<TChildProps>): Component<HocProps & TChildProps>;
}
const hoc = function<TChildProps>(): (component: Component<TChildProps>) => Component<HocProps & TChildProps) {
    return (Child: Component<TChildProps>) => {
        class MyHOC extends React.Component<HocProps & TChildProps, void> {
            // Implementation skipped for brevity
        }
        return MyHOC;
    }
}
export default hoc;

换句话说,hoc是一个产生实际 HOC 的函数。这个 HOC(我相信)是一个接受Component。由于我事先不知道包装的组件是什么,所以我使用通用类型TChildProps定义包装组件的 props 的形状。该函数还返回一个Component。返回的组件接受包装组件的 props(同样,使用通用类型键入TChildProps) and它本身需要一些道具(类型HocProps)。当使用返回的组件时,所有的 props(都HocProps以及包裹的道具Component)应提供。

现在,当我尝试使用 HOC 时,我会执行以下操作:

// outside parent component
const WrappedChildComponent = hoc()(ChildComponent);

// inside parent component
render() {
    return <WrappedChild
                thingy={ 42 } 
                // Prop `foo` required by ChildComponent
                foo={ 'bar' } />
}

但我收到 TypeScript 错误:

TS2339: Property 'foo' does not exist on type 'IntrinsicAttributes & HocProps & {} & { children? ReactNode; }'

在我看来 TypeScript 并没有取代TChildProps与所需道具的形状ChildComponent。我怎样才能让 TypeScript 做到这一点?


聚会有点晚了。 我喜欢使用 Omit TypeScript 实用程序类型来解决这个问题。 文档链接:https://www.typescriptlang.org/docs/handbook/utility-types.html#omitk https://www.typescriptlang.org/docs/handbook/utility-types.html#omittk

import React, {ComponentType} from 'react';

export interface AdditionalProps {
    additionalProp: string;
}

export function hoc<P extends AdditionalProps>(WrappedComponent: ComponentType<P>) : ComponentType<Omit<P, 'additionalProp'>> {
    const additionalProp = //...
    return props => (
        <WrappedComponent
            additionalProp={additionalProp}
            {...props as any}
        />
    );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 TypeScript 编写 React 高阶组件 的相关文章

随机推荐

  • 如何隐藏div元素下方的文本光标

    我是 CSS 和 javascript 新手 我有一个搜索文本框 可以在其中添加任何搜索值 输入错误值后 会弹出一个 div 并显示 未找到记录 带有关闭按钮来关闭 div 当我将光标放在文本框上而不关闭弹出窗口后 我的光标显示在 div
  • @end 在实现上下文中丢失[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我没有足够
  • Android:使用隐式意图读取txt文件

    问题 我正在尝试使用隐式打开 txt 文件Intent ACTION GET CONTENT 并将文本文件内容存储到数组列表中 当我尝试使用 Uri 的文件路径打开文件时getPath 并创建一个BufferedReader对象从文本文件中
  • 遗留文件的 QVariantList 序列化

    我正在以旧的遗留文件格式 不是我们的 阅读 很明显 这种文件格式是使用序列化编写的 因此为了让我的生活更轻松 我在阅读时也做了同样的事情 在读取文件的某个时刻 一个段被识别为QMetaType QVariantList https doc
  • Gradle 同步失败:无法创建父目录 - Android Studio

    我在 Android Studio 中遇到意外错误 无法运行我的应用程序 C Users gradle caches modules 2 metadata 2 71 descriptors com android tools build g
  • 用于检查素数的 C++ 代码不起作用

    我在使用此 C 代码时遇到问题 整数num是一个我想检查它是否是质数的数字 然而这个程序总是返回 false 这可能很简单 但我找不到任何东西 for int i 2 i
  • 如何将用户添加到 sfguard

    我在用着symfony http www symfony project net1 2 与sfguard 1 4 1 http www symfony project org plugins sfGuardPlugin 在系统上注册新用户的
  • 无法获取 Kerberos 领域

    我是 Kerberos hive 的新手 想要使用 JDBC 连接 hive Kerberos 实现 gt gt org apache hadoop conf Configuration conf new gt gt org apache
  • 为什么使用keys()而不是%{..}会发生自动生存?

    这是我发现的一个微妙之处keys perl e use warnings use strict my d ab gt 1 my e keys d gt cd perl e use warnings use strict my d ab gt
  • Vue.js 如何计算总数?

    如何计算数组中的总金额 我将数据作为 prop 传递给子组件 但我被困在这里 当我控制台 log prop 时 它返回一个非常复杂的对象 我试过this values reduce 功能 但不起作用
  • Django项目重组:无法导入应用程序

    我正在尝试重组我的项目 以符合最新的 Two Scoops of Django 一书 针对 Django 1 11 中的建议 完成重组后 我的应用程序无法导入 secureDash project README rst config ini
  • “未知命令syncdb”运行“python manage.pysyncdb”

    我想创建一个名为 database1 sqlite 的数据库的表 因此我运行以下命令 python 管理 py 同步数据库 但是当我执行命令时 我收到以下错误 未知命令 syncdb 输入 manage py help 以了解用法 但当我跑
  • 在 android 4.4 中,将应用程序从最近的任务中删除会永久终止应用程序及其服务。知道为什么吗?

    与以前的版本不同 在 4 4 中 将应用程序从最近的任务中删除会永久杀死应用程序及其服务 如强制停止 即使它正在运行后台服务 它显示 0 个进程 1 个服务 但服务也不起作用 理想情况下 它不应该终止后台服务 并且在 4 3 之前的版本中也
  • System.InvalidCastException - 在调试中有效,在发布时失败

    UNHANDLED EXCEPTION System InvalidCastException Cannot cast from source type to destination type 06 11 19 39 01 690 I Mo
  • 如何在 CarPlay 模拟器上测试 iOS 应用程序

    我正在尝试开发一个与 CarPlay 兼容的 iOS 应用程序 根据这篇文章iOS CarPlay API 是公开的吗 如何集成CarPlay https stackoverflow com questions 22372095 is io
  • Android 中缩小(或裁剪)对话框背景

    我有一个高分辨率图像 假设为 1900x1200 我想将其用作对话框的背景 它被创建了 Dialog dialog new Dialog this dialog setContentView R layout dialog 对话框布局
  • 始终在 UWP 中的 FlipView 控件上显示导航箭头

    使用鼠标并将鼠标悬停在通用 Windows 平台 UWP 上时FlipView控制显示上一个 下一个导航按钮 然而 当使用触摸或笔时 它们仍然隐藏 这可能会让用户感到困惑 不期待额外的内容 我希望导航按钮始终可见 我怎样才能做到这一点 我们
  • 将第二个全局管理员添加到 Azure AD B2C?

    如何为 Azure AD B2C 添加第二个全局管理员 我们是否将它们添加为访客帐户并分配该访客 GA 添加普通用户时 它说我们无法添加 dot state fl us 电子邮件 我们应该授权它 还是会搞砸我们的主要租户 Azure AD
  • 防止用户生成的内容破坏布局?

    我有一个包含一些用户生成的内容的网站 我希望能够将布局的标记以及用户生成的内容的标记分开 这样 u g 内容就不会破坏网站布局 用户生成的内容是可信的 因为它来自我网络上的已知用户组 但尽管如此 只允许一小部分 html 标签 p ul o
  • 使用 TypeScript 编写 React 高阶组件

    我正在写一个反应高阶组件 HOC https facebook github io react docs higher order components html使用 TypeScript HOC 应该比包装组件多接受一个 prop 所以我