JSX元素的包装器函数,通过泛型类型化



目前此功能在上运行良好

function wrapElement(elem: JSX.Element) {
return ({ ...props }) => React.cloneElement(elem, { ...props })
}

我这样使用它,因为这样我就可以获得顺风类的intelliSense

const Btn = wrapElement(<button className="[A LOT OF TAILWIND UTILITY CLASSES]" />)

但我正试图让它返回与接收到的类型相同的类型,这样我就可以为内在HTML元素上的属性获取intelliSense。目前推断的类型是

function wrapElement(elem: JSX.Element): ({ ...props }: {
[x: string]: any;
}) => React.FunctionComponentElement<any>.FunctionComponentElement<any> 

我尝试了一些东西,但都失败了,出现了各种各样的错误,在这一点上,我觉得这可能很糟糕,但也许我不明白什么?

基本上不可能从JSX.Element中获得正确的道具。可以实现您想要的设计,但您应该将元素名称和道具作为单独的参数传入,而不是传入JSX.Element

此代码可以接受像'button'或任何React组件这样的元素名称。它返回一个具有相同道具的函数组件。我不会从返回的组件中删除任何道具,因为看起来你是在使用它来设置默认值,而不是删除需求。

import React, { ComponentType, ComponentProps } from "react";
const wrapElement = <
C extends keyof JSX.IntrinsicElements | ComponentType<any>
>(
Component: C,
presetProps: Partial<ComponentProps<C>>
) => (props: ComponentProps<C>) => {
const merged: ComponentProps<C> = { ...presetProps, ...props };
return <Component {...merged} />;
};
const Btn = wrapElement("button", {
className: "[A LOT OF TAILWIND UTILITY CLASSES]"
});
const Dbl = wrapElement(Btn, { onClick: () => alert("clicked") });
const Test = () => {
return <Dbl>Click</Dbl>;
};

打字游戏场链接

您可能希望自定义合并行为以组合classNamestyle属性,而不是覆盖它们。

注意:当我尝试像<Component {...presetProps} {...props} />那样内联合并道具时,我得到了一个奇怪的错误";类型Partial<ComponentProps<C>> & ComponentProps<C>不可分配给类型IntrinsicAttributes & LibraryManagedAttributes<C, any>"所以这就是为什么我在单独的一行上合并道具,并将类型注释为ComponentProps<C>,而不是推断的类型Partial<ComponentProps<C>> & ComponentProps<C>

最新更新