使用 TypeScript 实现 CSS 断点 mixin 的问题

问题描述

基于 https://tobbelindstrom.com/blog/how-to-create-a-breakpoint-mixin-with-styled-components/ 我试图在 TypeScript 中做同样的事情,但我没有输入这个函数

import { css } from 'styled-components';
import { breakpoints } from './_variables';

export const respondTo = Object.keys(breakpoints).reduce(
  (accumulator,label) => {
    accumulator[label] = (...args) => css`
      @media (min-width: ${breakpoints[label]}) {
        ${css(...args)};
      }
    `;
    return accumulator;
  },{}
);

我尝试过这样的事情:

export const respondTo = Object.keys(breakpoints).reduce<Record<string,Function>>(
  (accumulator,label) => {
    accumulator[label] = (...args: Array<String>) => css`
      @media (min-width: ${breakpoints[label]}) {
        ${css(...args)};
      }
    `;
    return accumulator;
  },{}
);

但它不断抛出错误。现在,它给了我

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.   No index signature with a parameter of type 'string' was found on type '{}'.  TS7053

breakpoints[label]

解决方法

这是有效的

import { css } from "styled-components";

const breakpoints = {
  xs: "480px",sm: "768px",md: "992px",lg: "1200px"
};

type cssParams = Parameters<typeof css>;
const keys = Object.keys(breakpoints) as Array<keyof typeof breakpoints>;

export const respondTo = keys.reduce((accumulator,label) => {
  accumulator[label] = (...args: cssParams) => {
    return css`
      @media (min-width: ${breakpoints[label]}) {
        ${css(...args)};
      }
    `;
  };
  return accumulator;
},{} as Record<keyof typeof breakpoints,Function>);

问题是breakpoints[label]Object.keys()返回类型string[],所以label变成string,这不是breakpoints的有效键.

或者,您可以将 breakpoints 重新键入为 Record<string,string> 之类的内容。

我还添加了 cssParams,它会在解决此问题后为您提供帮助 ;)