在样式化组件中键入css函数

Tho*_*hia 0 typescript styled-components

我正在按照文档中的示例创建媒体模板,并且我真的很努力地键入要传递给css函数的参数(示例中的纯JS版本):

const sizes = {
  desktop: 992
}

const media = Object.keys(sizes).reduce((acc, label) => {

  acc[label] = (...args) => css`    // <----- how to type args

    @media(max-width: ${sizes[label]}px) {
      ${css(...args)}
    }

  `

  return acc
}, {})
Run Code Online (Sandbox Code Playgroud)

如果您知道TS但不了解样式组件,args则它是带标签的模板文字,因此我将这样使用该media对象:

media.desktop`
  background-color: blue;
  ${variable}
`
Run Code Online (Sandbox Code Playgroud)

我尝试键入argsas,TemplateStringsArray但TS抱怨,因为扩展参数必须是array类型的(我认为是类型,但是某种程度上无法识别)。如果我将类型更改为TemplateStringsArray[],则该css()函数会抱怨,因为它期望至少1个参数,但收到0或更多。

Tit*_*mir 5

一个标签模板的签名应该是(literals: TemplateStringsArray, ...placeholders: any[]) => string其中literals在模板中的字符串,placeholders是变量值。

如果您只想将所有参数传递给,则css可以使用call。Typescript不允许您直接传播,因为css具有ts编译器尝试检查的必需参数:

acc[label] = (...args: any[]) => css`  
  @media(max-width: ${sizes[label]}px) {
    ${css.call(undefined, ...args)}
  }

`
Run Code Online (Sandbox Code Playgroud)

可以正确指定media.*功能类型的完全类型化版本为:

const sizes = {
    desktop: 992
}

const media = Object.keys(sizes).reduce((acc, label) => {

    acc[label] = (literals: TemplateStringsArray, ...placeholders: any[]) => css`      
    @media(max-width: ${sizes[label]}px) {
        ${css(literals, ...placeholders)}
    }

    `;
    return acc
}, {} as Record<keyof typeof sizes, (l: TemplateStringsArray, ...p: any[]) => string>)
Run Code Online (Sandbox Code Playgroud)


Mat*_*iuk 5

Titian Cernicova-Dragomir 解决方案是伟大的,但对我不起作用。它产生一个带逗号的字符串。所以我添加joincss功能。

import { css } from "styled-components";

const sizes = {
  desktop: 730,
};

const media = Object.keys(sizes).reduce(
  (acc, label) => {
    acc[label] = (literals: TemplateStringsArray, ...placeholders: any[]) =>
      css`
        @media (max-width: ${sizes[label]}px) {
          ${css(literals, ...placeholders)};
        }
      `.join("");
    return acc;
  },
  {} as Record<
    keyof typeof sizes,
    (l: TemplateStringsArray, ...p: any[]) => string
  >,
);

export default media;
Run Code Online (Sandbox Code Playgroud)