0

我正在尝试在我正在构建的样板项目中使用 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>

我有许多这样的道具,我想将它们添加到我所有的 Glamorous 生成的元素中。因此,我创建了一个如下所示的辅助函数:

export const special = (glam: any, styles: object[]): GBPComp =>{
  return glam([styles as CSSStyleDeclaration[], specialProps]);
};

WherespecialProps表示一个函数(如上面的那个),它将各种道具添加到我的样式声明数组中。

我打算像这样使用它:

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>. 它们可能是HTMLAnchorElementorHTMLTableElement等​​。

我如何能够动态生成我的GBPComp类型,以便将这些道具(即layoutwidth)添加到所有返回的类型?这样以下内容将在 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>
4

1 回答 1

1

如果您不想要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
  }
]);
于 2018-03-07T03:59:04.590 回答