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

Add withTheme definition #521

Merged
merged 4 commits into from
Mar 1, 2017

Conversation

patrick91
Copy link
Contributor

See #483

@Igorbek Igorbek self-requested a review February 20, 2017 17:58
Copy link
Contributor

@Igorbek Igorbek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I also recently found that typings did not cover all the API.
In addition to inline comments, there's a definition of the styled-component module (with theme type parameter), where need to add this method also.


type Component<P> = ComponentClass<P> | StatelessComponent<P>;
type Component<P> = ComponentClass<P> | StatelessComponent<P> | PureComponent<P, any>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think PureComponent should be here. PureComponent is an instance, but here must be a constructor.
What the use case required this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw how withRouter was implemented in React Router, they were also using PureComponent. I'll remove this :)

@@ -199,6 +199,8 @@ export interface ThemedStyledComponentsModule<T> {
declare const styled: StyledInterface;

export const css: ThemedCssFunction<any>;
export function withTheme<C extends Component<any>>(component: C): C;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. it does not reflect that the resulting component does not have theme prop
  2. component parameter must have a theme prop
  3. has no strong type theming support (theme prop must be of the same type as theme)
  4. we do not need to capture component type and return it, we only need to capture props type and always return ComponentClass

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. what's the point for this? you need to specify the theme prop anyway, like this:
class MyComponent extends React.Component<ThemeProps<{}>, {}> {
  render() {
    const { theme } = this.props;

    console.log("Current theme: ", theme);

    return <h1>Hello</h1>;
  }
}

export default withTheme(MyComponent);
  1. yeah, that would be helpful, will change :)
  2. same as 1
  3. will change

Copy link
Contributor

@Igorbek Igorbek Feb 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest something like this here:

export function withTheme<P extends { theme?: T; }, T>(component: Component<P>): ComponentClass<rest(P, 'theme')>;

where rest(P, 'theme') is a new type operator that is going to be landed with TS smth like 2.3, unfortunately (microsoft/TypeScript#13470).
I do not have any other ideas how to express removing a property from a generic type. Do you have any?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you need to remove the property?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An inner class is required to have theme prop and an implementer may want to have it required:

interface MyComponentProps {
  theme: MyTheme; // I want have this required
  text: string;
}
class MyComponent extends React.Component<MyComponentProps, {}> {
  ...
}

<MyComponentProps theme={theme} text={text} /> // ok
<MyComponentProps text={text} /> // error, I can't use without theme

so after applying the withTheme, the component will lose theme prop:

interface MyThemedComponentProps {
  text: string;
}
const MyThemedComponent: ComponentClass<MyThemedComponentProps> = withTheme(MyComponent);

<MyThemedComponent text={text} /> // now that is ok
<MyThemedComponent theme={theme} text={text} /> // and now that is an error, because there's no theme prop anymore

@Igorbek
Copy link
Contributor

Igorbek commented Feb 23, 2017

How it going, @patrick91 ? Do you need any help?

@patrick91
Copy link
Contributor Author

I'm pretty busy these days! I'll try to find some time soon :)

@patrick91
Copy link
Contributor Author

@Igorbek I don't see any way to remove the theme prop any than using rest. Also we need to specify the theme prop in the component interface, otherwise we won't be able to use use it (see: http://s.patrick.wtf/FSirCmZ9dz) so I was thinking to require the them prop on the component. What do you think?

@patrick91
Copy link
Contributor Author

I can't mark the theme prop as required, it will complain when using the component.
Let me know if you have any other feedbacks :)

Copy link
Contributor

@Igorbek Igorbek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I've been thinking about this and haven't come up with something useful as well.
We'll be waiting for better HOC support in typescript

Copy link
Member

@mxstbr mxstbr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let's shipit?

@patrick91
Copy link
Contributor Author

patrick91 commented Mar 1, 2017 via email

@mxstbr mxstbr merged commit c5bb046 into styled-components:master Mar 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants