frenic / csstype

Strict TypeScript and Flow types for style based on MDN data
MIT License
1.73k stars 72 forks source link

`flexDirection` and `flexWrap` not inferred correctly #144

Closed maecapozzi closed 2 years ago

maecapozzi commented 2 years ago

I've been working with vanilla-extract and noticed the flexDirection and flexWrap properties are not inferred correctly.

See this code sandbox for a reproduction.

The following code causes a TS error:

import { styleVariants } from '@vanilla-extract/css';

const exampleVariants = {
  primary: {
    flexDirection: 'row',
    flexWrap: 'nowrap'
  },
  secondary: {
    flexDirection: 'column',
    flexWrap: 'nowrap'
  },
};

export const brokenExampleVariant = styleVariants(
  exampleVariants,
  (variant) => ({
    flexDirection: variant.flexDirection,
  }),
);

Error

No overload matches this call.
  Overload 1 of 2, '(styleMap: Record<string | number, StyleRule>, debugId?: string | undefined): Record<string | number, string>', gave the following error.
    Argument of type '{ primary: { flexDirection: string; flexWrap: string; }; secondary: { flexDirection: string; flexWrap: string; }; }' is not assignable to parameter of type 'Record<string | number, StyleRule>'.
      Property 'primary' is incompatible with index signature.
        Type '{ flexDirection: string; flexWrap: string; }' is not assignable to type 'StyleRule'.
          Type '{ flexDirection: string; flexWrap: string; }' is not assignable to type 'StyleWithSelectors'.
            Types of property 'flexDirection' are incompatible.
              Type 'string' is not assignable to type 'CSSVarFunction | FlexDirection | (FlexDirection | undefined)[] | (CSSVarFunction | FlexDirection | undefined)[] | undefined'.
  Overload 2 of 2, '(data: { primary: { flexDirection: string; flexWrap: string; }; secondary: { flexDirection: string; flexWrap: string; }; }, mapData: <Key extends "primary" | "secondary">(value: { primary: { flexDirection: string; flexWrap: string; }; secondary: { ...; }; }[Key], key: Key) => StyleRule, debugId?: string | undefined): Record<...>', gave the following error.
    Type 'string' is not assignable to type 'CSSVarFunction | FlexDirection | (FlexDirection | undefined)[] | (CSSVarFunction | FlexDirection | undefined)[] | undefined'.ts(2769)
index.d.ts(1657, 3): The expected type comes from property 'flexDirection' which is declared here on type 'StyleRule'

I believe this is due to CSS type not correctly typing these two css properties.

frenic commented 2 years ago

I'm pretty sure this is caused by type widening. Change to this and it should be fixed:

const exampleVariants = {
  primary: {
    flexDirection: 'row',
    flexWrap: 'nowrap'
  },
  secondary: {
    flexDirection: 'column',
    flexWrap: 'nowrap'
  },
} as const;