Styled components Typescript

Hi, can someone help how to fully type this function with typescript?

interface Size {
  small: number;
  medium: number;
  large: number;
  xLarge: number;
}
const size: Size = {
  small: 500,
  medium: 960,
  large: 1140,
  xLarge: 1400,
};

export const below = Object.keys(size).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media (max-width: ${size[label] / 16}em) {
      ${css(...args)}
    }
  `;
  return acc;
}, {});

I solved it, by if any one want to know how I wrote the code I wrote it like this.

import { css } from 'styled-components';

interface Size {
  small: number;
  medium: number;
  large: number;
  xLarge: number;
}

const size: Size = {
  small: 500,
  medium: 960,
  large: 1140,
  xLarge: 1400,
} as const;

type CssParams = Parameters<typeof css>;

type StyleFnMap = Record<keyof Size, (...args: CssParams) => any>;

// Object.keys() is typed as `string[]`. This function lets use slightly better typing.
const typedKeys = <T extends {}>(obj: T) => Object.keys(obj) as Array<keyof T>;

export const below = typedKeys(size).reduce((acc, label: keyof Size) => {
  acc[label] = (...args) => css`
    @media (max-width: ${size[label] / 16}em) {
      ${css(...args)}
    }
  `;
  return acc;
}, {} as StyleFnMap);

// Object.keys() is typed as `string[]`. This function lets use slightly better typing.
export const above = typedKeys(size).reduce((acc, label: keyof Size) => {
  acc[label] = (...args) => css`
    @media (min-width: ${size[label] / 16}em) {
      ${css(...args)}
    }
  `;
  return acc;
}, {} as StyleFnMap);

1 Like

This great @ciszekmarcell! Thanks for sharing how you solved this.

1 Like