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

[TypeScript] createStyles() does not have smart property hints in the vscode editor #11693

Closed
1 of 2 tasks
chilbi opened this issue Jun 3, 2018 · 9 comments
Closed
1 of 2 tasks

Comments

@chilbi
Copy link

chilbi commented Jun 3, 2018

  • This is a v1.x issue (v0.x is no longer maintained).
  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

good

Current Behavior

bad

Context

export default function createStyles<K extends string = string>(styles: StyleRules<K>): StyleRules<K>;

Your Environment

Tech Version
Material-UI v1.2.0
TypeScript v2.8.3
@franklixuefei
Copy link
Contributor

franklixuefei commented Jun 19, 2018

@chilbi You'd have to do something like this for now:

const styles: StyleRulesCallback = ({ palette, spacing, typography }) => createStyles<StyleRules>({
  ...
});

or

const styles = ({ palette, spacing, typography }: Theme) => createStyles<StyleRules>({
  ...
});

@pelotom Any better suggestions ?😄

@BrendonSled
Copy link

@franklixuefei if you go the createStyles<StyleRules> route, you lose the autocomplete on the this.props.classes

@franklixuefei
Copy link
Contributor

franklixuefei commented Jun 19, 2018

@BrendonSled I think it's one way or the other. For now I don't have a solution that's easy enough to cover both cases. The only solution I can think of is to explicitly pass in the keys, like WithStyles<'rule1' | 'rule2'>, rather than using typeof styles as the type param of WithStyles. However, this is ugly.

Also, you can put the keys into the type param of StyleRules, like StyleRules<'rule1' | 'rule2'>, and still use typeof styles in WithStyles. Essentially, both solutions are the same, and, ugly.

It's kind of like a "chicken and egg` problem. See below for a possible solution.

type classList =
  | 'root'
  | 'rule1'
  | 'rule2'
;

const styles = ({ palette, spacing, typography }: Theme) => createStyles<StyleRules<classList>>({
  root: {...}, // intellisense enabled
  rule1: {...},
  rule2: {...}
});

...

classes.root; // intellisense enabled
...

@pelotom
Copy link
Member

pelotom commented Jun 19, 2018

The whole purpose of the createStyles(...) function is to infer your class keys from what you put in ..., so there's no point ever providing a type parameter to it. If you're going to explicitly provide the class keys from the outside, just do

const styles: StyleRulesCallback<ClassKey> = ({ palette, spacing, typography }) => ({
  ...
});

@BrendonSled
Copy link

@pelotom using the createStyles(...) function breaks autocomplete inside the CSS properties. Which is the issue outlined above by the OC.

A temporary workaround I've found if you want autocomplete on the CSS properties and inferred class keys is to just add CSSProperties to each class key, like so

const styles = (theme) => ({
  root: {...} as CSSProperties,
  rule1: {...} as CSSProperties,
});
...
classes.root; // intellisense enabled

@franklixuefei
Copy link
Contributor

franklixuefei commented Jun 19, 2018

@BrendonSled I like your workaround. as CSSProperties can be annoying, but at least we don't have to specify classList anymore.
To me, TBH, the autocompletion inside the CSS properties is more important.

I wish type widening had never been invented.

@pelotom
Copy link
Member

pelotom commented Jun 19, 2018

@BrendonSled yep, I was just responding to later comments. This seems like maybe an issue worth raising with the TypeScript team? I would think that if the as CSSProperties annotation is sufficient to get autocompletion then it should also work with createStyles.

@MoazAlkharfan
Copy link

I actually did the following

const styles = (theme: Theme) => createStyles<StyleRules>(
    {
        classname: {
            somecssprop: "cssvalue"
        },
    }
);

interface IComponentOwnProps {
    classes: {[T in keyof ReturnType<typeof styles>]: T};
}

@eps1lon
Copy link
Member

eps1lon commented Aug 13, 2018

@chilbi This should be resolved with #12456 which was released in 1.5.0.

Edit:
It seems like this is indeed a bug in typescript. microsoft/TypeScript#22077 looks like the same issue.

We have a fix for now but if this question comes up again we can forward to the typescript issues.

@pelotom pelotom closed this as completed Aug 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants