Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add fallbacks to jssStyle #1493

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

hosseinmd
Copy link
Member

Corresponding Issue(s):

What Would You Like to Add/Fix?

Todo

  • Add test(s) that verify the modified behavior
  • Add documentation if it changes public API

Expectations on Changes

Changelog

@hosseinmd hosseinmd requested a review from kof as a code owner April 10, 2021 22:52
@kof kof requested a review from a team April 11, 2021 07:06
@kof
Copy link
Member

kof commented Apr 15, 2021

The change seems correct to me, fallbacks are optional, this is waiting for a review from anyone from @cssinjs/typescript team

@ITenthusiasm
Copy link
Member

Hmmm... At a first glance, the change doesn't appear to be harmful. However, I have seen things behave strangely when something like Record<keys, values> or { [key: string]: value } is mixed with an explicit interface as it is here. So...actually it may not work out. I might explore in the TypeScript playground for a bit.

May I ask what the fallback property is intended for?

@ITenthusiasm
Copy link
Member

Hmmm. I'm more confident that this won't work now. In the TypeScript playground I tried:

type Blah = { pizza: string | number } & { [K: string]: number };

const blah: Blah = {
  pizza: "1",
}

and got an error because "1" is not a number. Things like { [key: string]: value } kind of absorb everything. So the additional explicit interfaces you try to define end up being negated/nullified, effectively. This is another issue that I've had many headaches with in my side projects.

Were the tests run for this?

@kof
Copy link
Member

kof commented Apr 15, 2021

@ITenthusiasm fallbacks is basically how we describe css fallbacks in js, because we can't use the same property twice with objects https://cssinjs.org/jss-syntax?v=v10.6.0#fallbacks

@hosseinmd
Copy link
Member Author

This change working correct, please review again.

@ITenthusiasm
Copy link
Member

It would probably be good to have type tests to go with the change.

@ITenthusiasm
Copy link
Member

Interesting. So if the second type in the OR type chain is removed, then the error I mentioned earlier gets created. Seems inconsistent... hm....

@ITenthusiasm
Copy link
Member

Yeah. Due to the inconsistencies, I don't think I'm willing to approve this unless there are some robust tests to show nothing unexpected would happen.

@hosseinmd
Copy link
Member Author

i added few test.

@hosseinmd
Copy link
Member Author

Interesting. So if the second type in the OR type chain is removed, then the error I mentioned earlier gets created. Seems inconsistent... hm....

Please show by example which this change is inconsistent.

I removed the second type in the OR but that working again. So that is consistent.

@hosseinmd
Copy link
Member Author

@kof this type working Good. Please review again @kof.

@kof
Copy link
Member

kof commented Apr 23, 2021

@hosseinmd I need to delegate the decision to @ITenthusiasm because he is much deeper than I am in TS

@hosseinmd
Copy link
Member Author

I add array to test too.

@hosseinmd
Copy link
Member Author

hosseinmd commented Apr 23, 2021

@ITenthusiasm The idea of JssStyle is not throw error anyway, that is just for helping to VSCode intellisense. This is the main mission of second OR and JssValue to prevent throwing error.

@hosseinmd
Copy link
Member Author

type Blah = { pizza: string | number } & { [K: string]: number };

const blah: Blah = {
  pizza: "1",
}

This example is not correct. You should use OR, like original code.

@hosseinmd
Copy link
Member Author

Screen Shot 2021-04-30 at 2 27 13 PM

VSCode intellisense popup is recognized the display property type correctly

@hosseinmd hosseinmd requested a review from kof May 6, 2021 07:12
@kof
Copy link
Member

kof commented Jun 27, 2021

@hosseinmd I just pulled it and it doesn't compile, I get tons of errors, is it because of recent changes in master?

@kof kof added the typescript label Jun 27, 2021
@kof
Copy link
Member

kof commented Jun 27, 2021

Lets finish this one off!

@hosseinmd
Copy link
Member Author

I rebase master to this branch

@kof
Copy link
Member

kof commented Jul 2, 2021

typescript shows errors to me, what am I missing?

@hosseinmd
Copy link
Member Author

Fixed

@kof
Copy link
Member

kof commented Jul 4, 2021

When I run it locally, I see 64 errors

Oleg-9EJHCC:jss isonen$ yarn tsc
yarn run v1.15.2
$ /Users/isonen/work/cssinjs/jss/node_modules/.bin/tsc
packages/jss/src/index.d.ts:19:13 - error TS2456: Type alias 'JssStyle' circularly references itself.

19 export type JssStyle<Props = any, Theme = undefined> = {
               ~~~~~~~~

packages/jss/src/index.d.ts:20:15 - error TS2315: Type 'JssStyle' is not generic.

20   fallbacks?: JssStyle<Props, Theme> | (JssStyle<Props, Theme>[])
                 ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:20:41 - error TS2315: Type 'JssStyle' is not generic.

20   fallbacks?: JssStyle<Props, Theme> | (JssStyle<Props, Theme>[])
                                           ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:25:11 - error TS2315: Type 'JssStyle' is not generic.

25         | JssStyle<Props, Theme>
             ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:26:51 - error TS2315: Type 'JssStyle' is not generic.

26         | Func<Props, Theme, NormalCssValues<K> | JssStyle<undefined, undefined> | undefined>
                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:32:11 - error TS2315: Type 'JssStyle' is not generic.

32         | JssStyle<Props, Theme>
             ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:33:41 - error TS2315: Type 'JssStyle' is not generic.

33         | Func<Props, Theme, JssValue | JssStyle<undefined, undefined> | undefined>
                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:43:5 - error TS2315: Type 'JssStyle' is not generic.

43   | JssStyle<Props, Theme>
       ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:44:11 - error TS2315: Type 'JssStyle' is not generic.

44   | Array<JssStyle<Props, Theme>>
             ~~~~~~~~~~~~~~~~~~~~~~

packages/jss/src/index.d.ts:46:24 - error TS2315: Type 'JssStyle' is not generic.

46   | Func<Props, Theme, JssStyle<undefined, undefined> | string | null | undefined>
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

packages/jss/tests/jss-tests.ts:85:3 - error TS2578: Unused '@ts-expect-error' directive.

85   // @ts-expect-error
     ~~~~~~~~~~~~~~~~~~~

packages/jss/tests/jss-tests.ts:94:3 - error TS2578: Unused '@ts-expect-error' directive.

94   // @ts-expect-error
     ~~~~~~~~~~~~~~~~~~~

packages/jss/tests/types/Styles.ts:29:21 - error TS7006: Parameter 'props' implicitly has an 'any' type.

29     justifyContent: props => (props.flag ? 'center' : undefined)
                       ~~~~~

packages/jss/tests/types/Styles.ts:40:9 - error TS7006: Parameter 'props' implicitly has an 'any' type.

40   func: props => ({
           ~~~~~

packages/jss/tests/types/Styles.ts:50:13 - error TS7006: Parameter 'props' implicitly has an 'any' type.

50   funcNull: props => null,
               ~~~~~

packages/jss/tests/types/Styles.ts:51:17 - error TS7006: Parameter 'props' implicitly has an 'any' type.

51   funcWithTerm: props => ({
                   ~~~~~

packages/jss/tests/types/Styles.ts:53:5 - error TS2783: 'height' is specified more than once, so this usage will be overwritten.

53     height: props.flag ? 330 : 400,
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  packages/jss/tests/types/Styles.ts:60:5
    60     ...(props.flag && {
           ~~~~~~~~~~~~~~~~~~~
    61       height: 288
       ~~~~~~~~~~~~~~~~~
    62     })
       ~~~~~~
    This spread always overwrites this property.

packages/jss/tests/types/Styles.ts:78:27 - error TS7031: Binding element 'flag' implicitly has an 'any' type.

78   rootParamDeclaration: ({flag, theme}) => ({
                             ~~~~

packages/jss/tests/types/Styles.ts:78:33 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

78   rootParamDeclaration: ({flag, theme}) => ({
                                   ~~~~~

packages/jss/tests/types/Styles.ts:85:31 - error TS7031: Binding element 'flag' implicitly has an 'any' type.

85     innerParamDeclaration1: ({flag, theme}) => '',
                                 ~~~~

packages/jss/tests/types/Styles.ts:85:37 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

85     innerParamDeclaration1: ({flag, theme}) => '',
                                       ~~~~~

packages/jss/tests/types/Styles.ts:86:31 - error TS7031: Binding element 'flag' implicitly has an 'any' type.

86     innerParamDeclaration2: ({flag, theme}) => ({
                                 ~~~~

packages/jss/tests/types/Styles.ts:86:37 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

86     innerParamDeclaration2: ({flag, theme}) => ({
                                       ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:29:1 - error TS2578: Unused '@ts-expect-error' directive.

29 // @ts-expect-error
   ~~~~~~~~~~~~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:31:29 - error TS7031: Binding element 'innerTheme' implicitly has an 'any' type.

31   themeNotAllowed: ({theme: innerTheme}) => ({
                               ~~~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:58:5 - error TS2578: Unused '@ts-expect-error' directive.

58     // @ts-expect-error
       ~~~~~~~~~~~~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:94:40 - error TS2559: Type '{ property: string; }' has no properties in common with type '{ theme?: Theme | undefined; }'.

94 const themeArg7ClassesPass = themeArg7(expectedCustomProps)
                                          ~~~~~~~~~~~~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:114:16 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

114   themeOnly: ({theme}) => ({
                   ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:133:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

133   propsAndTheme: ({property, theme}) => ({
                       ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:133:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

133   propsAndTheme: ({property, theme}) => ({
                                 ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:153:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

153   propsAndTheme: ({property, theme}) => ({
                       ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:153:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

153   propsAndTheme: ({property, theme}) => ({
                                 ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:175:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

175     singleValue: ({property, theme}) => '',
                       ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:175:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

175     singleValue: ({property, theme}) => '',
                                 ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:176:16 - error TS7031: Binding element 'property' implicitly has an 'any' type.

176     nestOne: ({property, theme}) => ({
                   ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:176:26 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

176     nestOne: ({property, theme}) => ({
                             ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:188:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

188     singleValue: ({property, theme}) => '',
                       ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:188:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

188     singleValue: ({property, theme}) => '',
                                 ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:191:27 - error TS7031: Binding element 'property' implicitly has an 'any' type.

191       innerSingleValue: ({property, theme}) => '',
                              ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:191:37 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

191       innerSingleValue: ({property, theme}) => '',
                                        ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:192:21 - error TS7031: Binding element 'property' implicitly has an 'any' type.

192       secondNest: ({property, theme}) => ({
                        ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:192:31 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

192       secondNest: ({property, theme}) => ({
                                  ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:205:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

205     singleValue: ({property, theme}) => '',
                       ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:205:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

205     singleValue: ({property, theme}) => '',
                                 ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:208:27 - error TS7031: Binding element 'property' implicitly has an 'any' type.

208       innerSingleValue: ({property, theme}) => '',
                              ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:208:37 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

208       innerSingleValue: ({property, theme}) => '',
                                        ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:211:33 - error TS7031: Binding element 'property' implicitly has an 'any' type.

211         innerMostSingleValue: ({property, theme}) => '',
                                    ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:211:43 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

211         innerMostSingleValue: ({property, theme}) => '',
                                              ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:212:22 - error TS7031: Binding element 'property' implicitly has an 'any' type.

212         thirdNest: ({property, theme}) => ({
                         ~~~~~~~~

packages/react-jss/tests/types/createUseStyles.ts:212:32 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

212         thirdNest: ({property, theme}) => ({
                                   ~~~~~

packages/react-jss/tests/types/createUseStyles.ts:233:44 - error TS2559: Type '{ property: string; }' has no properties in common with type '{ theme?: Theme | undefined; }'.

233 const noThemeArg8ClassesPass = noThemeArg8(expectedCustomProps)
                                               ~~~~~~~~~~~~~~~~~~~

packages/react-jss/tests/types/docs.tsx:21:16 - error TS7031: Binding element 'spacing' implicitly has an 'any' type.

21     padding: ({spacing}) => spacing || 10
                  ~~~~~~~

packages/react-jss/tests/types/docs.tsx:23:14 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

23   myLabel: ({theme, ...props}) => ({
                ~~~~~

packages/react-jss/tests/types/docs.tsx:60:12 - error TS7006: Parameter 'props' implicitly has an 'any' type.

60   myLabel: props => ({
              ~~~~~

packages/react-jss/tests/types/docs.tsx:78:14 - error TS7006: Parameter 'props' implicitly has an 'any' type.

78     padding: props => props.spacing || 10
                ~~~~~

packages/react-jss/tests/types/withStyles.tsx:54:22 - error TS7031: Binding element 'property' implicitly has an 'any' type.

54     someClassName: ({property}) => '',
                        ~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:66:12 - error TS7031: Binding element 'property' implicitly has an 'any' type.

66     [1]: ({property}) => '',
              ~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:99:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

99   someClassName: ({property}) => '',
                      ~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:109:20 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

109   someClassName: ({theme}) => '',
                       ~~~~~

packages/react-jss/tests/types/withStyles.tsx:119:20 - error TS7031: Binding element 'property' implicitly has an 'any' type.

119   someClassName: ({property, theme}) => '',
                       ~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:119:30 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

119   someClassName: ({property, theme}) => '',
                                 ~~~~~

packages/react-jss/tests/types/withStyles.tsx:129:10 - error TS7031: Binding element 'property' implicitly has an 'any' type.

129   [1]: ({property, theme}) => '',
             ~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:129:20 - error TS7031: Binding element 'theme' implicitly has an 'any' type.

129   [1]: ({property, theme}) => '',
                       ~~~~~

packages/react-jss/tests/types/withStyles.tsx:167:1 - error TS2578: Unused '@ts-expect-error' directive.

167 // @ts-expect-error
    ~~~~~~~~~~~~~~~~~~~


Found 64 errors.

@kof
Copy link
Member

kof commented Sep 5, 2021

@hosseinmd honestly, how did you make it pass tsc compiler ... there are dozens of errors

@kof
Copy link
Member

kof commented Sep 6, 2021

Ok I updated to typescript 4.4.2 and now the only 2 errors I get are these:

167 // @ts-expect-error
    ~~~~~~~~~~~~~~~~~~~

packages/react-jss/tests/types/withStyles.tsx:170:12 - error TS2345: Argument of type '(theme: MyTheme) => Styles<string, unknown, null>' is not assignable to parameter of type 'Styles<string, unknown, MyTheme> | ((theme: MyTheme) => Styles<string, unknown, undefined>)'.
  Type '(theme: MyTheme) => Styles<string, unknown, null>' is not assignable to type '(theme: MyTheme) => Styles<string, unknown, undefined>'.
    Type 'Styles<string, unknown, null>' is not assignable to type 'Styles<string, unknown, undefined>'.
      'string' index signatures are incompatible.
        Type 'string | MinimalObservable<string | JssStyle<any, undefined> | null | undefined> | JssStyle<unknown, null> | JssStyle<unknown, null>[] | ((data: { ...; }) => string | ... 2 more ... | undefined)' is not assignable to type 'string | MinimalObservable<string | JssStyle<any, undefined> | null | undefined> | JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | ((data: unknown) => string | ... 2 more ... | undefined)'.
          Type '{ fallbacks?: JssStyle<unknown, null> | JssStyle<unknown, null>[] | undefined; } & { alignContent?: AlignContent | MinimalObservable<AlignContent | JssStyle<any, undefined> | undefined> | JssStyle<...> | ((data: { ...; }) => AlignContent | ... 1 more ... | undefined) | undefined; ... 763 more ...; vectorEffect?: Vec...' is not assignable to type 'string | MinimalObservable<string | JssStyle<any, undefined> | null | undefined> | JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | ((data: unknown) => string | ... 2 more ... | undefined)'.
            Type '{ fallbacks?: JssStyle<unknown, null> | JssStyle<unknown, null>[] | undefined; } & { alignContent?: AlignContent | MinimalObservable<AlignContent | JssStyle<any, undefined> | undefined> | JssStyle<...> | ((data: { ...; }) => AlignContent | ... 1 more ... | undefined) | undefined; ... 763 more ...; vectorEffect?: Vec...' is not assignable to type '{ fallbacks?: JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | undefined; } & { [K: string]: JssValue | MinimalObservable<JssValue | JssStyle<any, undefined> | undefined> | JssStyle<...> | ((data: unknown) => JssValue | ... 1 more ... | undefined); }'.
              Type '{ fallbacks?: JssStyle<unknown, null> | JssStyle<unknown, null>[] | undefined; } & { alignContent?: AlignContent | MinimalObservable<AlignContent | JssStyle<any, undefined> | undefined> | JssStyle<...> | ((data: { ...; }) => AlignContent | ... 1 more ... | undefined) | undefined; ... 763 more ...; vectorEffect?: Vec...' is not assignable to type '{ fallbacks?: JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | undefined; }'.
                Types of property 'fallbacks' are incompatible.
                  Type 'JssStyle<unknown, null> | JssStyle<unknown, null>[] | undefined' is not assignable to type 'JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | undefined'.
                    Type '{ fallbacks?: JssStyle<unknown, null> | JssStyle<unknown, null>[] | undefined; } & { alignContent?: AlignContent | MinimalObservable<AlignContent | JssStyle<any, undefined> | undefined> | JssStyle<...> | ((data: { ...; }) => AlignContent | ... 1 more ... | undefined) | undefined; ... 763 more ...; vectorEffect?: Vec...' is not assignable to type 'JssStyle<unknown, undefined> | JssStyle<unknown, undefined>[] | undefined'.

170 withStyles(passingFunctionNullTheme)(SimpleComponent)
               ~~~~~~~~~~~~~~~~~~~~~~~~


Found 2 errors.

I have no clue why they happen and its frustrating up to the point to throw ts out altogether and make it someone else's problem.

@kof
Copy link
Member

kof commented Sep 6, 2021

I pushed my state to this branch: https://github.com/cssinjs/jss/tree/fallbacksType would appreciate help @cssinjs/typescript

@kof
Copy link
Member

kof commented Sep 6, 2021

Oh those 2 errors happen on master too when upgrading ts to 4.4.2, maybe @ITenthusiasm knows what that is

@kof
Copy link
Member

kof commented Sep 6, 2021

we should discuss it in this separate PR #1550

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants