@types/xxxx package and had problems.Definitions by: in index.d.ts) so they can respond.@erikdstock @ifiokjr @sbardian @pomber @wKovacs64 @prateekkathal
Hi! I've encountered a type error while trying to compose reusable style objects.
TLDR: Type 'SystemCssProperties' is not assignable to type 'UseThemeFunction'.
import { SystemCssProperties } from "@styled-system/css";
const buttonStyles: SystemCssProperties = {
font: "inherit",
background: "papayawhip",
border: "none"
};
const styles = { buttonStyles };
const _ = (
<button
type="button"
sx={styles.buttonStyles} // 馃敟
>
click me
</button>
);
Typing buttonStyles as SxStyleProp works, but then you can't spread it onto other objects like
sx={{ ...styles.buttonReset, background: "blue" }}
For the first snippet:
error TS2322: Type 'SystemCssProperties' is not assignable to type '(SystemCssProperties & Record<string, string | number | SystemCssProperties | CSSPseudoSelectorProps | ... 4
more ... | Record<...>>) | ... 4 more ... | undefined'.
Type 'SystemCssProperties' is not assignable to type 'UseThemeFunction & Record<string, string | number |
SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | VariantProperty | UseThemeFunction | (string | ... 1 more ... | null)[] | Record<...>>'.
Type 'SystemCssProperties' is not assignable to type 'UseThemeFunction'.
Type 'SystemCssProperties' provides no match for the signature '(theme: any): SystemStyleObject'.
165 <button type="button" sx={styles.buttonStyles}>
~~
node_modules/@types/theme-ui/index.d.ts:157:5
157 sx?: SxStyleProp;
~~
The expected type comes from property 'sx' which is declared here on type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'
and for the second one:
Type '{ background: string; clipPath?: string | SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | ... 4 more ... | undefined; ... 428 more ...; fontWeight?: string | ... 8 more ... | undefined; }' is not assignable to type '(SystemCssProperties & Record<string, string | number | SystemCssProperties | CSSPseudoSelectorProps | ... 4 more ... | Record<...>>) | ... 4 more ... | undefined'.
Type '{ background: string; clipPath?: string | SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | ... 4 more ... | undefined; ... 428 more ...; fontWeight?: string | ... 8 more ... | undefined; }' is not assignable to type 'UseThemeFunction & Record<string, string | number | SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | VariantProperty | UseThemeFunction | (string | ... 1 more ... | null)[] | Record<...>>'.
Type '{ background: string; clipPath?: string | SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | ... 4 more ... | undefined; ... 428 more ...; fontWeight?: string | ... 8 more ... | undefined; }' is not assignable to type 'UseThemeFunction'.
Type '{ background: string; clipPath?: string | SystemCssProperties | CSSPseudoSelectorProps | CSSSelectorObject | ... 4 more ... | undefined; ... 428 more ...; fontWeight?: string | ... 8 more ... | undefined; }' provides no match for the signature '(theme: any): SystemStyleObject'.ts(2322)
It "fixed" it locally with a small change to SxStyleProp definition.
export type SxStyleProp = SystemStyleObject | (SystemStyleObject &
Record<
string,
| SystemStyleObject
| ResponsiveStyleValue<number | string>
| Record<string, SystemStyleObject | ResponsiveStyleValue<number | string>>
>);
The workaround fails at runtime when extra properties don't match what styled-system/css expects.
Example:
const badSystemStyleObject: SystemStyleObject = {
background: "blue",
foo(_arg1: unknown, arg2: { bar: string }): string {
// This will raise TypeError: Cannot read property 'bar' of undefined on
// https://github.com/styled-system/styled-system/blob/master/packages/css/src/index.js#L191
return arg2.bar;
}
};
Two things:
What are you trying to do with that foo function? I would expect the error you're getting, regardless of types, as those functions only receive one argument (the theme). arg2 will always be undefined, as far as I know.
I wonder if there is any reason why we can't reduce the SxStyleProp type to simply:
export type SxStyleProp = SystemStyleObject;
Everything I've thrown at sx still passes type checking with that definition, and it fixes your issue.
What are you trying to do with that foo function? I would expect the error you're getting, regardless of types, as those functions only receive one argument (the theme). arg2 will always be undefined, as far as I know.
This was just a counterexample for my change.
I wonder if there is any reason why we can't reduce the SxStyleProp type to simply:
OMG, why did I miss it?!
This will be it. This Record nesting was redundant since SystemStyleObject is already recursive (through CSSSelectorObject).
Thanks so much @wKovacs64!
This seem to break string literals:
column: {
display: 'flex',
flexDirection: 'column',
}
=>
[tsl] ERROR in .../CreateClipButton.tsx
TS2322: Type '{ display: string; flexDirection: string; }' is not assignable to type 'SystemStyleObject'.
Type '{ display: string; flexDirection: string; }' is not assignable to type 'CSSSelectorObject'.
Property 'display' is incompatible with index signature.
Type 'string' is not assignable to type 'SystemStyleObject'.
Heads up for anyone else that came to this ticket because they got "Type 'string' is not assignable to type 'SystemStyleObject'." randomly while mucking about with sx objects: check your props for typos. In my case I was getting that error from using borderRadiusBottomRight instead of borderBottomRightRadius.
This seems to be still happening for me, but only when I use certain css properties, such as appearance, whiteSpace and textAlign:
const buttonBase = {
display: "inline-flex",
// appearance: "none",
alignItems: "center",
justifyContent: "center",
// textAlign: "center",
lineHeight: "inherit",
textDecoration: "none",
fontSize: "inherit",
fontWeight: "bold",
// whiteSpace: "nowrap",
verticalAlign: "middle",
m: 0,
px: 3,
border: 0,
borderRadius: "button",
cursor: "pointer",
letterSpacing: "0.05em"
};
export const styleProps = (
color: string,
size: ButtonSize,
variant: ButtonVariant
): SystemStyleObject => {
switch (variant) {
case "filled":
return {
...buttonBase,
bg: color,
color: "white",
fill: "white",
"&:focus,&:hover": {
bg: darken("primary", 0.05)
},
"&:active": {
bg: darken("primary", 0.1)
},
"&:disabled": {
bg: "disabled",
cursor: "default"
}
};
default:
throw new Error(`You chose an unimplemented Button Variant: ${variant}`);
}
};
This fails typescript on bg, color and fill with the error Type 'string' is not assignable to type 'SystemStyleObject'. if you uncomment any of appearance, textAlign or whiteSpace. It does not happen if I copy the baseButtonStyles directly into the object I'm returning. Not sure why.
Any thoughts?
@kristojorg Try explicitly typing buttonBase like so:
- const buttonBase = {
+ const buttonBase: SystemStyleObject = {
Most helpful comment
This seem to break string literals:
=>