我需要在React中使用forwardRef指定高阶组件的参数类型和返回类型。目前,我完成了以下实施。由于我尚未指定确切的ElementType,因此它可以工作,但并不完美。如果我尝试添加其他通用类型Element extends React.ElementType
,则会发生此错误:
Error:(34, 10) TS2322: Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ComponentProps<Element>>, "children" | Exclude<...> | Exclude<...>> & { ...; }' is not assignable to type 'IntrinsicAttributes & ComponentProps<Element> & Props & { children?: ReactNode; }'.
Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ComponentProps<Element>>, "children" | Exclude<...> | Exclude<...>> & { ...; }' is not assignable to type 'ComponentProps<Element>'.
如果我通过'div'对元素类型进行硬编码,则会出现以下错误:
Error:(32, 10) TS2769: No overload matches this call.
Overload 1 of 2, '(props: ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & Props, context?: any): ReactElement<...> | ... 1 more ... | null', gave the following error.
Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }' is not assignable to type 'IntrinsicAttributes & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & Props'.
Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }' is not assignable to type 'Props'.
'Props' could be instantiated with an arbitrary type which could be unrelated to 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }'.
Overload 2 of 2, '(props: PropsWithChildren<ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & Props>, context?: any): ReactElement<...> | ... 1 more ... | null', gave the following error.
Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }' is not assignable to type 'IntrinsicAttributes & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & Props & { ...; }'.
Type 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }' is not assignable to type 'Props'.
'Props' could be instantiated with an arbitrary type which could be unrelated to 'Pick<PropsWithChildren<withPermissionsProps & Props & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>, "slot" | ... 255 more ... | Exclude<...>> & { ...; }'.
import PermissionDenied from '@/components/PermissionDenied'
import cn from 'classnames'
import React from 'react'
import style from './withPermissions.module.scss'
export interface withPermissionsProps {
readable?: boolean
executable?: boolean
showPlaceholder?: boolean
}
export function withPermissions<Props>(
Component: React.ComponentType<
React.ComponentProps<React.ElementType> & Props
>,
): React.ForwardRefExoticComponent<
React.PropsWithoutRef<
withPermissionsProps & Props & React.ComponentProps<React.ElementType>
>
> {
return React.forwardRef(function withPermissions_(
{
className,
readable = false,
executable = false,
showPlaceholder = false,
...otherProps
},
ref,
) {
return (
((readable || executable) && (
<Component
{...otherProps}
ref={ref}
className={cn(
style.withPermissions,
{
[style.withPermissions_readonly]: readable && !executable,
[style.withPermissions_executeOnly]: executable && !readable,
},
className,
)}
/>
)) ||
(showPlaceholder && <PermissionDenied />) ||
null
)
})
}
export default withPermissions
还要确保交叉点类型不包含我尝试省略的相同键,但这并没有帮助。
也许以前有人遇到过这个问题,我认为这是一件很普通的事情,必须先做一次,才不应该成为问题。