typescript - Bedre typet funksjon for å generere mediespørringer


Jeg følger med på dette innlegget: https://medium.com/@samuelresua/easy-media-queries-in-styled-components-690b78f50053

Jeg har laget følgende i Typescript, men har måttet ty til å skrive til any mer enn jeg tror jeg burde:

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;
}, {});

Som et resultat har jeg ingen hjelp i IDE-en min når jeg skriver stiler i mediaforespørselsblokkene mine:

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

Noen som vet hvordan jeg kan forbedre min media-funksjon?

Svar #1

Jeg tror ikke dette er et TypeScript-problem, men snarere et IntelliSense-plugin-problem.

Fra TypeScripts perspektiv er innholdet mellom backticks av typen TemplateStringsArray. TypeScript er ikke klar over gyldige CSS-egenskaper da det ser en streng-array.

Jeg tror valideringen gjøres på plugin-nivå av typescript-styled-plugin.

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

Jeg vil sende inn en forespørsel om funksjon eller en feilmelding her.

Svar #2

Hvis jeg forstår riktig, vil du bli kvitt any.

Slik kan du gjøre det:

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;
  },
  {}
);

Relaterte artikler