Search code examples
reactjstypescriptemotion

Typescript dose not allow to put a variable as a value to styled array


I've got a weird problem with TypeScript and Emotion.css with react

This code works fine:

import styled from '@emotion/styled-base';
const Layout = styled('div')([
    {
        height: 48,
        color: 'white',
        background: Brand01,
        width: 142,
        padding: '12px 16px',
        textAlign: 'center'
    },
    {
        fontStyle: 'normal',
        fontWeight: 'normal',
        fontSize: '14px',
        lineHeight: '23px'
    }
]);

But on this:

const b = {
    fontStyle: 'normal',
    fontWeight: 'normal',
    fontSize: '14px',
    lineHeight: '23px'
};
const Layout = styled('div')([
    {
        height: 48,
        color: 'white',
        background: Brand01,
        width: 142,
        padding: '12px 16px',
        textAlign: 'center'
    },
    b
]);

Typescript is throwing an error like this:

ERROR in [at-loader] ./src/components/buttons/Button.tsx:13:2 
    TS2322: Type '{ height: number; color: string; background: string; width: number; padding: string; textAlign: string; }' is not assignable to type 'string'.

ERROR in [at-loader] ./src/components/buttons/Button.tsx:21:2 
    TS2322: Type '{ fontStyle: string; fontWeight: string; fontSize: string; lineHeight: string; }' is not assignable to type 'string'.

ERROR in /frontend/src/components/buttons/Button.tsx
Type error: Type '{ height: number; color: string; background: string; width: number; padding: string; textAlign: string; }' is not assignable to type 'string'.  TS2322

    11 | };
    12 | const Layout = styled('div')([
  > 13 |        {
       |        ^
    14 |                height: 48,
    15 |                color: 'white',
    16 |                background: Brand01,

ERROR in ./src/components/buttons/Button.tsx
Type error: Type '{ fontStyle: string; fontWeight: string; fontSize: string; lineHeight: string; }' is not assignable to type 'string'.  TS2322

    19 |                textAlign: 'center'
    20 |        },
  > 21 |        b
       |        ^
    22 | ]);

And I don't get it, why a variable should be assignable to type 'string' but a plain object should not?)

Thanks for any help

TypeScript: 3.3.3
Emotion: 10.0.7
React: 16.8

P.S. Stackoverflow dose not allow me to put this question without additional information about question, because too many code i've put here. But I think code much clearly explained my question, so I've written this paragraph to pass the validation :)


Solution

  • The difference is that in the failing case, the type of b is inferred before it is passed to the the styled function whereas when it passed directly as a function argument its type can be inferred correctly.

    This is covered in some detail in this issue

    The solution proposed there is to annotate your object declarations:

    import styled, { CSSObject } from '@emotion/styled';
    
    const b: CSSObject = {
        fontStyle: 'normal',
        fontWeight: 'normal',
        fontSize: '14px',
        lineHeight: '23px'
    };