在 styled-components 中输入 css 函数

Typing the css function in styled-components

我正在按照文档中的 example 创建媒体模板,但我真的很难输入要传递给 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
}, {})

如果你知道 TS 但不知道 styled-components,args 是一个标记的模板文字,所以我会这样使用 media 对象:

media.desktop`
  background-color: blue;
  ${variable}
`

我尝试将 args 键入为 TemplateStringsArray,但 TS 抱怨因为传播参数需要是 array 类型(我认为是,但不知何故无法识别) .如果我将类型更改为 TemplateStringsArray[]css() 函数会报错,因为它需要至少 1 个参数,但收到了 0 个或更多。

标记模板的签名应为 (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)}
  }

`

正确指定 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>)

Titian Cernicova-Dragomir 很棒,但对我不起作用。 它产生一个带逗号的字符串。 所以我将 join 添加到 css 函数。

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;