Лучше типизированная функция для генерации медиа-запросов - PullRequest
8 голосов
/ 27 марта 2020

Я следую за этим сообщением: https://medium.com/@samuelresua / easy-media-query-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;
}, {});

В результате я не помогаю в своей среде IDE, когда пишу стили в своих блоках медиа-запросов. :

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

Кто-нибудь знает, как я могу улучшить свою media функцию?

Ответы [ 3 ]

5 голосов
/ 30 марта 2020

Я считаю, что это не проблема TypeScript, а скорее проблема с подключаемым модулем IntelliSense.

С точки зрения TypeScript содержимое между обратными чертами имеет тип TemplateStringsArray. TypeScript не знает о допустимых свойствах CSS, поскольку видит массив строк.

Я считаю, что проверка выполняется на уровне плагина с помощью typcript-styled-plugin .

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

Я бы отправил запрос о функции или отчет об ошибке здесь .

1 голос
/ 12 апреля 2020

Если я правильно понимаю, вы хотите избавиться от any.

Вот как вы можете это сделать:

import {
  css,
  CSSObject,
  SimpleInterpolation,
  FlattenSimpleInterpolation,
} from 'styled-components';

type ObjectMap<T> = {[key: string]: T};

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

export const media = Object.keys(breakpoints).reduce(
  (
    acc: {
      [key: string]: (
        first: TemplateStringsArray | CSSObject,
        ...interpolations: SimpleInterpolation[]
      ) => FlattenSimpleInterpolation;
      // ^^^ this is the first implementation of  `BaseThemedCssFunction`
    },
    label
  ) => {
    acc[label] = (...args) => css`
      @media (min-width: ${breakpoints[label]}px) {
        ${css(...args)};
      }
    `;
    return acc;
  },
  {}
);
0 голосов
/ 12 апреля 2020

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 :)
  })
}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...