样式化的组件TypeScript

Col*_*rdo 4 javascript typescript reactjs styled-components

styled-components在正常的React.js中使用,我可以做到:

const Container = styled.div({
  userSelect: `none !important`,
})
Run Code Online (Sandbox Code Playgroud)

但是使用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)

Run Code Online (Sandbox Code Playgroud)

解决此问题的最佳方法是什么?

我不想使用styled.div模板字符串方法,因为我发现它不太灵活。

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

const flex = {
  flex: display: flex,
  col: flexDirection: `column`
}

const FlexRow = styled.div({
  ...flex.flex,
})

const FlexCol = styled.div({
   ...flex.flex,
   ...flex.col,
})
Run Code Online (Sandbox Code Playgroud)

p.s*_*w.g 5

更新:在进一步调查中,在我弄清楚实际情况之前,@ Vincent似乎走在正确的轨道上。

import styled, { CSSObject } from "styled-components";

const Container = styled.div({
  userSelect: "none !important"
} as CSSObject);
Run Code Online (Sandbox Code Playgroud)

将产生以下错误:

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)
Run Code Online (Sandbox Code Playgroud)

因此,是的,即使在TypeScript中,样式化组件的确确实支持此语法,只是不理解!important后缀。这是您可能会稍作修改的解决方案:

const important = <T extends string>(s: T): T => `${s} !important` as T;

const Container = styled.div({
  userSelect: important("none"),
});
Run Code Online (Sandbox Code Playgroud)

这是一个有点哈克(铸造"none !important""none",当它显然不是),但它让你的风格的CSS道具干净,并传递类型的检查。


原始答案:我对样式化组件的语法不熟悉(看起来有点像JSS,但不完全一样)。

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

const Container = styled.div`
  user-select: none !important;
`;
Run Code Online (Sandbox Code Playgroud)


Vin*_*ent 5

它无法识别,!important因此只需将其转换为任何安静的打字稿即可。

styled.div({
  userSelect: 'none !important'  as any
});
Run Code Online (Sandbox Code Playgroud)

编辑-解释为什么它有效

这很简单。如果您使用像atom 这样的IDE,您可以“转到” userSelect 属性的类型。类型是UserSelectProperty并且它的值必须恰好是其中之一。

export type Globals = "-moz-initial" | "inherit" | "initial" | "revert" | "unset";
export type UserSelectProperty = Globals | "-moz-none" | "all" | "auto" | "contain" | "element" | "none" | "text";
Run Code Online (Sandbox Code Playgroud)

由于none !important不是一个选项,因此您必须将其转换为任何选项。