garronej / tss-react

✨ Dynamic CSS-in-TS solution, based on Emotion
https://tss-react.dev
MIT License
659 stars 37 forks source link

Migration from MUI 4 to 5 - "Type 'string' is not assignable to type '"relative" #72

Closed NicklasWallgren closed 2 years ago

NicklasWallgren commented 2 years ago

Hey,

I'm currently migrating from MUI 4 to version 5 and have encountered some weird behaviour.

I've got a two files tableFilterStyles.ts and TableFilter.tsx containing

tableFilterStyles.ts

import { Theme } from "@mui/material/styles";

export const tableFilterStyles = (theme: Theme) =>
  ({
    root: {
      position: "relative"
    },
    ....
  });

TableFilter.tsx

import { makeStyles } from 'tss-react/mui';
import { tableFilterStyles } from "../../styles";

const useStyles = makeStyles()(tableFilterStyles);

....

For some particular reason Typescript doesn't like the position.relative object. "Type 'string' is not assignable to type '"relative" Everything else works expect "position".

I guess I need to add a return type to the tableFilterStyles function, maybe cssObjectByRuleNameOrGetCssObjectByRuleName?

Do you have any idea?

If I pass the style directly it works

const useStyles = makeStyles()( (theme: Theme) => ({
  root: {
    position: "relative"
  },
}));

Thanks!

The whole error message;

Argument of type '(theme: Theme) => { root: { position: string; }; checkboxes: { position: string; }; }' is not assignable to parameter of type 'Record<"root" | "checkboxes", CSSObject> | ((theme: Theme, params: void, classes: Record<never, string>) => Record<"root" | "checkboxes", CSSObject>)'.   Type '(theme: Theme) => { root: { position: string; }; checkboxes: { position: string; }; }' is not assignable to type '(theme: Theme, params: void, classes: Record<never, string>) => Record<"root" | "checkboxes", CSSObject>'.     Call signature return types '{ root: { position: string; }; checkboxes: { position: string; }; }' and 'Record<"root" | "checkboxes", CSSObject>' are incompatible.       The types of 'root.position' are incompatible between these types.         Type 'string' is not assignable to type '"relative" | "-moz-initial" | "inherit" | "initial" | "revert" | "unset" | "-webkit-sticky" | "absolute" | "fixed" | "static" | "sticky" | ("relative" | "-moz-initial" | "inherit" | ... 8 more ... | undefined)[] | Position[] | undefined'.
NicklasWallgren commented 2 years ago

Record<string, CSSObject> solved it.

garronej commented 2 years ago

Hi,

You just need to add as const

-position: "relative"
+position: "relative" as const

If you don't, TypeScript see the value of position as a string and it's not happy because he is expecting "relative" | "absolute" | ...

NicklasWallgren commented 2 years ago

@garronej Thanks for the explanation.

I solved the issue by defining the return type Record<string, CSSObject>. But as const would probably have worked as well.

export const tableFilterStyles = (theme: Theme): Record<string, CSSObject> =>
  ({
    root: {
      position: "relative"
    },
    ....
  });