更好的类型函数来生成媒体查询

Mis*_*pic 8 typescript styled-components

我正在关注这篇文章:https : //medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053

我在 Typescript 中创建了以下内容,但不得不求助于any比我必须的更多的输入,我敢肯定:

const breakpoints: ObjectMap<number> = {
  small: 767,
  medium: 992,
  large: 1200,
  extraLarge: 1240
};

export const media = Object.keys(breakpoints).reduce((acc: { [key: string]: (...args: any) => any }, label) => {
  acc[label] = (...args) => css`
     @media (min-width: ${breakpoints[label]}px) {
        ${css(...args as [any])};
     }
  `;
  return acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

因此,当我在媒体查询块中编写样式时,我的 IDE 没有任何帮助:

styled.button<Props>`
  background: red; /* this must be a valid style */
  ${({ theme }) => theme.media.large`
      background: blue;
      foo: bar; /* this isn't caught */
   `
Run Code Online (Sandbox Code Playgroud)

有谁知道我如何改善我的media功能?

sun*_*sen 5

我相信这不是 TypeScript 问题,而是 IntelliSense 插件问题。

从 TypeScript 的角度来看,反引号之间的内容是 type TemplateStringsArray。TypeScript 不知道有效的 CSS 属性,因为它看到的是一个字符串数组。

我相信验证是通过typescript-styled-plugin在插件级别完成的

https://github.com/styled-components/vscode-styled-components/pull/41

我会在这里提交功能请求或错误报告。


Rob*_*ore 0

styled-components允许您将对象用于 CSS 属性以及模板字符串,并且 TypeScript 编译器可以更好地理解对象。尝试这个:

const breakpoints: ObjectMap<number> = {
  small: 767,
  medium: 992,
  large: 1200,
  extraLarge: 1240
};

export const media = (size: keyof typeof breakpoints, properties: CSSObject) => ({[`@media (min-width: ${breakpoints[size]})`]: properties});

const MyButton = styled.button<Props>(({ theme }) => ({
  background: red, // this must be a valid style
  ...theme.media('large', {
    background: blue // this is also validated :)
  })
}));
Run Code Online (Sandbox Code Playgroud)