代码之家  ›  专栏  ›  技术社区  ›  Colin Ricardo

样式化组件TypeScript

  •  3
  • Colin Ricardo  · 技术社区  · 6 年前

    styled-components

    const Container = styled.div({
      userSelect: `none !important`,
    })
    

    但是,对于TypeScript,我得到了一个错误:

    Argument of type '{ userSelect: string; }' is not assignable to parameter of type 'TemplateStringsArray'.
      Object literal may only specify known properties, and 'userSelect' does not exist in type 'TemplateStringsArray'.ts(2345)
    
    

    最好的解决方法是什么?

    styled.div 模板字符串的方法,因为我发现它灵活得多。

    例如,对于模板字符串,我们不能执行以下操作:

    const flex = {
      flex: display: flex,
      col: flexDirection: `column`
    }
    
    const FlexRow = styled.div({
      ...flex.flex,
    })
    
    const FlexCol = styled.div({
       ...flex.flex,
       ...flex.col,
    })
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   p.s.w.g    6 年前

    在进一步的调查中,在我弄清楚到底发生了什么之前,@Vincent似乎走上了正确的道路。

    import styled, { CSSObject } from "styled-components";
    
    const Container = styled.div({
      userSelect: "none !important"
    } as CSSObject);
    

    将生成以下错误:

    Conversion of type '{ userSelect: "none !important"; }' to type 'CSSObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
      Type '{ userSelect: "none !important"; }' is not comparable to type 'Properties<string | number>'.
        Types of property 'userSelect' are incompatible.
          Type '"none !important"' is not comparable to type '"contain" | "all" | "-moz-initial" | "inherit" | "initial" | "revert" | "unset" | "auto" | "none" | "text" | "-moz-none" | "element" | undefined'.ts(2352)
    

    所以是的,样式化组件确实支持这种语法,即使在TypeScript中,它只是不理解 !important 后缀。以下是您可能更喜欢的稍加修改的解决方案:

    const important = <T extends string>(s: T): T => `${s} !important` as T;
    
    const Container = styled.div({
      userSelect: important("none"),
    });
    

    有点粗糙(铸造) "none !important" 作为 "none" 但它会保持样式化CSS道具的干净并通过类型检查。


    原始答案:

    我建议使用标准语法。样式化组件通常是这样编写的:

    const Container = styled.div`
      user-select: none !important;
    `;
    
        2
  •  4
  •   Vincent    6 年前

    它不认识 !important

    styled.div({
      userSelect: 'none !important'  as any
    });
    

    编辑-解释为什么这样做

    UserSelectProperty 它的值必须是其中之一。

    export type Globals = "-moz-initial" | "inherit" | "initial" | "revert" | "unset";
    export type UserSelectProperty = Globals | "-moz-none" | "all" | "auto" | "contain" | "element" | "none" | "text";
    

    none !important

        3
  •  0
  •   Brad Adams    5 年前

    我只是在寻找一些稍微相关的东西时遇到了这个问题。我知道这个问题已经解决了,但是我已经使用样式化组件很长一段时间了,而且从来没有看到过您所引用的对象语法,我假设包括它是为了允许在js选项中采用其他css。

    不过,我之所以要发表评论是因为您的flex示例,您可以使用标记的模板文本实现非常类似的效果:

    const flex = {
      flex: 'display: flex',
      col: 'flex-direction: column'
    }
    
    const FlexRow = styled.div`
      ${flex.flex};
    `
    
    const FlexCol = styled.div`
      ${flex.flex};
      ${flex.col};
    `
    

    快乐风格组件