我试图在我正在构建的样板项目中使用PayPal的Glamorous CSS-in-JS库,该项目还利用了TypeScript。
Glamorous允许您像这样添加道具到元素:
const Section = glamorous.section([
{
...styles
},
({size}: any){
if(size === 'big') return {fontSize: '48px';}
else if(size === 'small') return {fontSize: '12px';}
},
({alignment}: any){
if(alignment === 'left') return {textAlign: 'left'}
else if(alignment === 'right') return {textAlign: 'right'}
}
]);
这样您就可以像这样使用JSX中的元素:
<Section size="big"></Section>
我有很多这样的道具,我想将它们添加到我所有迷人的元素中。因此,我创建了一个如下所示的辅助函数:
export const special = (glam: any, styles: object[]): GBPComp =>{
return glam([styles as CSSStyleDeclaration[], specialProps]);
};
其中
specialProps
表示一个函数(如上述函数),它将各种道具添加到我的样式声明数组中。我打算这样使用它:
const Section = special(glamorous.section, [
{
...styles
}
]);
然后,我想输入
specialProps
提供的所有道具以用于我的JSX。因此,我试图创建我的GBPComp
类型,如下所示:export type GBPComp = React.StatelessComponent<CSSProperties&ExtraGlamorousProps&React.HTMLProps<HTMLElement>&{
layout?: string,
width?: string
}>;
问题在于并非所有返回的元素都必须具有
React.HTMLProps<HTMLElement>
属性。它们可能是HTMLAnchorElement
或HTMLTableElement
等。我如何能够动态生成我的
GBPComp
类型,从而将那些道具(即layout
和width
)添加到所有返回的类型中?这样,以下内容即可在TypeScript中正常工作:const Section = special(glamorous.section, [
{
...styles
}
]);
const Anchor = special(glamorous.a, [
{
...styles
}
]);
<a href="#" layout="someString">This is an Anchor</a>
<section layout="someString">This is a Section</section>
最佳答案
如果不希望每个元素都使用React.HTMLProps<HTMLElement>
,而不是对React.HTMLProps<HTMLElement>
进行硬编码,则可以对GBPComp
使用泛型,如下所示
export type GBPComp<ExtraProps> = React.StatelessComponent<React.CSSProperties & ExtraGlamorousProps & ExtraProps & {
layout: string,
width: string
}>;
并且
special()
也接受ExtraProps
作为泛型,并像这样传递给GBPComp
export function special<ExtraProps>(glam: any, styles: object[], ...specialProps): GBPComp<ExtraProps> {
return glam([styles as CSSStyleDeclaration[], ...specialProps]);
};
现在,您可以将
React.HTMLProps<HTMLAnchorElement>
道具分配给Anchor
const Anchor = special<React.HTMLProps<HTMLAnchorElement>>(glamorous.a, [
{
...styles
}
]);