Using forwardRef with HOC in TypeScript.

huangapple go评论65阅读模式
英文:

Using forwardRef with HOC in typescript

问题

你想要的中文翻译是:

"我正在尝试创建一个React高阶组件(HOC),但遇到了问题,以下是我的代码:

import React, { FC, forwardRef } from 'react'
import { ButtonBase, ButtonBaseProps } from '@mui/material'

export default function withTouchRipple<PROPS>(OriginalComponent: FC<PROPS>) {
  return forwardRef((props: any, ref) => <ButtonBase {...props} ref={ref} component={OriginalComponent} />)
}
  • 我在使用MUI。

它运行良好。然而,我想从props: any中移除any类型,应该是PROPS,这样给定组件OriginalComponent的props接口将在外部可见。

但是,当我这样做时,TypeScript会报错。"

请注意,我只翻译了你的代码和问题陈述,没有包括错误信息。

英文:

I am trying to make a react HOC, but I am having problems, here's my code:

import React, { type FC, forwardRef } from &#39;react&#39;
import { ButtonBase, ButtonBaseProps } from &#39;@mui/material&#39;

export default function withTouchRipple&lt;PROPS&gt;(OriginalComponent: FC&lt;PROPS&gt;) {
  return forwardRef((props: any, ref) =&gt; &lt;ButtonBase {...props} ref={ref} component={OriginalComponent} /&gt;)
}
  • I am using MUI.

It works well. However, I want to remove the any type from props: any, it should be PROPS, so the interface of the props of the given component OriginalComponent will be visibie from outside.

but when I do so, typescript complains:

Here's the code after the change and here's the compile error:

import React, { type FC, forwardRef } from &#39;react&#39;
import { ButtonBase, ButtonBaseProps } from &#39;@mui/material&#39;

export default function withTouchRipple&lt;PROPS&gt;(OriginalComponent: FC&lt;PROPS&gt;) {
  return forwardRef((props: PROPS, ref) =&gt; &lt;ButtonBase {...props} ref={ref} component={OriginalComponent} /&gt;)
}
No overload matches this call.
  Overload 1 of 3, &#39;(props: { href: string; } &amp; { action?: Ref&lt;ButtonBaseActions&gt; | undefined; centerRipple?: boolean | undefined; children?: ReactNode; classes?: Partial&lt;ButtonBaseClasses&gt; | undefined; ... 10 more ...; touchRippleRef?: Ref&lt;...&gt; | undefined; } &amp; Omit&lt;...&gt; &amp; CommonProps &amp; Omit&lt;...&gt;): Element&#39;, gave the following error.
    Type &#39;ForwardedRef&lt;unknown&gt;&#39; is not assignable to type &#39;((instance: HTMLAnchorElement | null) =&gt; void) | RefObject&lt;HTMLAnchorElement&gt; | null | undefined&#39;.
      Type &#39;MutableRefObject&lt;unknown&gt;&#39; is not assignable to type &#39;((instance: HTMLAnchorElement | null) =&gt; void) | RefObject&lt;HTMLAnchorElement&gt; | null | undefined&#39;.
        Type &#39;MutableRefObject&lt;unknown&gt;&#39; is not assignable to type &#39;RefObject&lt;HTMLAnchorElement&gt;&#39;.
          Types of property &#39;current&#39; are incompatible.
            Type &#39;unknown&#39; is not assignable to type &#39;HTMLAnchorElement | null&#39;.
  Overload 2 of 3, &#39;(props: { component: FC&lt;PROPS&gt;; } &amp; { action?: Ref&lt;ButtonBaseActions&gt; | undefined; centerRipple?: boolean | undefined; children?: ReactNode; ... 11 more ...; touchRippleRef?: Ref&lt;...&gt; | undefined; } &amp; Omit&lt;...&gt; &amp; CommonProps &amp; DistributiveOmit&lt;...&gt;): Element | null&#39;, gave the following error.
    Type &#39;PROPS &amp; { ref: ForwardedRef&lt;unknown&gt;; component: FC&lt;PROPS&gt;; }&#39; is not assignable to type &#39;IntrinsicAttributes &amp; { component: FC&lt;PROPS&gt;; } &amp; { action?: Ref&lt;ButtonBaseActions&gt; | undefined; centerRipple?: boolean | undefined; ... 12 more ...; touchRippleRef?: Ref&lt;...&gt; | undefined; } &amp; Omit&lt;...&gt; &amp; CommonProps &amp; DistributiveOmit&lt;...&gt;&#39;.
      Type &#39;PROPS &amp; { ref: ForwardedRef&lt;unknown&gt;; component: FC&lt;PROPS&gt;; }&#39; is not assignable to type &#39;DistributiveOmit&lt;PropsWithRef&lt;PROPS&gt;, keyof CommonProps | &quot;tabIndex&quot; | &quot;children&quot; | &quot;action&quot; | &quot;centerRipple&quot; | &quot;disabled&quot; | &quot;disableRipple&quot; | &quot;disableTouchRipple&quot; | ... 6 more ... | &quot;touchRippleRef&quot;&gt;&#39;.
  Overload 3 of 3, &#39;(props: DefaultComponentProps&lt;ExtendButtonBaseTypeMap&lt;ButtonBaseTypeMap&lt;{}, &quot;button&quot;&gt;&gt;&gt;): Element | null&#39;, gave the following error.
    Type &#39;ForwardedRef&lt;unknown&gt;&#39; is not assignable to type &#39;((instance: HTMLButtonElement | null) =&gt; void) | RefObject&lt;HTMLButtonElement&gt; | null | undefined&#39;.
      Type &#39;MutableRefObject&lt;unknown&gt;&#39; is not assignable to type &#39;((instance: HTMLButtonElement | null) =&gt; void) | RefObject&lt;HTMLButtonElement&gt; | null | undefined&#39;.
        Type &#39;MutableRefObject&lt;unknown&gt;&#39; is not assignable to type &#39;RefObject&lt;HTMLButtonElement&gt;&#39;.
          Types of property &#39;current&#39; are incompatible.
            Type &#39;unknown&#39; is not assignable to type &#39;HTMLButtonElement | null&#39;.ts(2769)
index.d.ts(805, 46): The expected type comes from property &#39;ref&#39; which is declared here on type &#39;IntrinsicAttributes &amp; { href: string; } &amp; { action?: Ref&lt;ButtonBaseActions&gt; | undefined; centerRipple?: boolean | undefined; children?: ReactNode; ... 11 more ...; touchRippleRef?: Ref&lt;...&gt; | undefined; } &amp; Omit&lt;...&gt; &amp; CommonProps &amp; Omit&lt;...&gt;&#39;
index.d.ts(805, 46): The expected type comes from property &#39;ref&#39; which is declared here on type &#39;IntrinsicAttributes &amp; { action?: Ref&lt;ButtonBaseActions&gt; | undefined; centerRipple?: boolean | undefined; children?: ReactNode; ... 11 more ...; touchRippleRef?: Ref&lt;...&gt; | undefined; } &amp; Omit&lt;...&gt; &amp; CommonProps &amp; Omit&lt;...&gt;&#39;

答案1

得分: 0

React.forwardRef 是一个通用函数,您可以按如下方式传递您的通用类型:

import { type FC, forwardRef } from "react";
import { ButtonBase } from "@mui/material";

export default function withTouchRipple<PROPS>(
  OriginalComponent: FC<PROPS>,
  displayName: string
) {
  const component = forwardRef<HTMLButtonElement, PROPS>((props, ref) => (
    <ButtonBase {...props} ref={ref} component={OriginalComponent} />
  ));
  component.displayName = displayName;
  return component;
}
英文:

React.forwardRef is a generic function and you can pass your generic type as follows:

import { type FC, forwardRef } from &quot;react&quot;;
import { ButtonBase } from &quot;@mui/material&quot;;

export default function withTouchRipple&lt;PROPS&gt;(
  OriginalComponent: FC&lt;PROPS&gt;,
  displayName: string
) {
  const component = forwardRef&lt;HTMLButtonElement, PROPS&gt;((props, ref) =&gt; (
    &lt;ButtonBase {...props} ref={ref} component={OriginalComponent} /&gt;
  ));
  component.displayName = displayName;
  return component;
}

huangapple
  • 本文由 发表于 2023年5月18日 02:10:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定