stitchesjs / stitches

[Not Actively Maintained] CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.
https://stitches.dev
MIT License
7.76k stars 254 forks source link

Typescript error when using utils with array input prop #763

Open mathisobadia opened 3 years ago

mathisobadia commented 3 years ago

Bug report

Describe the bug

When using an util in the stitches config that has an input prop of type: value: [Stitches.ScaleValue<"colors">, number]) there is a typescript error when trying to use that util e.g. colorUtil: ["$red", 0.5] the error is Type 'string' is not assignable to type 'ScaleValue<"colors">' on the $red part, The really weird thing is that autocompletes works correctly and offers the correct $red option.

To Reproduce

Here is a code sandbox reproducing the error, wait for the sandbox to be fully loaded and the error will appear on line 13 https://codesandbox.io/s/late-glade-9wxlt?file=/src/App.tsx:238-262 This is a fork of the base stitches code sandbox I found online. I upgraded dependencies to latest typescript and stitches

Expected behavior

No typescript error

Screenshots

issue

System information

Additional context

It looks like the typescript version doesn't change the result.

peduarte commented 3 years ago

We haven't had a chance to focus on this yet, but we did take a look.

It's related to the fact we only check the first type in the array: https://github.com/modulz/stitches/blob/canary/packages/core/types/css-util.d.ts#L47-L62

So, for example, the following code would also fail:

import { createStitches } from "@stitches/core";
import type * as Stitches from "@stitches/core";

export const { css } = createStitches({
  theme: {
    colors: {
      red: "red"
    },
    space: {
      1: '10px'
    }
  },
  utils: {
    colorAndBackgroundColor: (value: [Stitches.ScaleValue<"colors">, Stitches.ScaleValue<"space">]) => ({
      color: value[0],
      backgroundColor: value[1],
    }),
  }
});

const test = css({
  colorAndBackgroundColor: ["$red", "$red"] // here, the second argument expects to be `$red` even though we are typing it as the space scale
});
joseDaKing commented 3 years ago

I have I kinda workaround which works by splitting the array values into multiple local variables. I would argue it is better because It would make it more composable, in other words, I can have multiple CSS mixings using the different utilities.

import { PropertyValue } from "@stitches/react";

import { Placement } from "../../types";

const directionVariableName = "$$direction";

const fromVariableName = "$$from";

const toVariableName = "$$to";

export const linearGradient = (value: "text" | "background" | "none") => {

    switch(value) {

        case "text":
            return {
                backgroundColor: "$$from",
                "@supports (-webkit-background-clip: text) and (-webkit-text-fill-color: transparent)": {
                    backgroundImage: `linear-gradient(to ${directionVariableName}, ${fromVariableName}, ${toVariableName})`,
                    "-webkit-background-clip": "text",
                    "-webkit-text-fill-color": "transparent"
                }
            };

        case "background":
            return {
                backgroundColor: "$$from",
                backgroundImage: `linear-gradient(to ${directionVariableName}, ${fromVariableName}, ${toVariableName})`,
            };

        default: 
            return {
                backgroundImage: "none"
            };
    }
}

export const linearGradientDirection = (direction: Placement) => ({
    [directionVariableName]: direction.split("-").join(" ")
});

export const linearGradientFrom = (from: | PropertyValue<"color">) => ({
    [fromVariableName]: `$colors${from}`
});

export const linearGradientTo = (to: PropertyValue<"color">) => ({
    [toVariableName]: `$colors${to}`
});
berkaytheunicorn commented 3 years ago

Same issue here but with objects,

type TypographyToken = {
  family: ScaleValue<"font">;
  size: ScaleValue<"fontSizes">;
};
 typography: (value: TypographyToken) => {
      const { family, size } = value;
      return {
        fontFamily: family,
        fontSize: size,
        lineHeight: size,
      };
    },

error looks like this,

Screen Shot 2021-10-17 at 23 04 28

no suggestions either but works.

berkaytheunicorn commented 3 years ago

Btw, it also won't work with PropertyValue.


type TypographyToken = {
  family: PropertyValue<"fontFamily">;
  size: PropertyValue<"fontSize">;
};```
peduarte commented 3 years ago

Noted. Thank you all 🙏 We'll look into this soon.

seobie commented 2 years ago

It seems like it's not fixed yet 🥲