Skip to content

Commit

Permalink
Document the weird special case when props are empty
Browse files Browse the repository at this point in the history
  • Loading branch information
pelotom committed Oct 15, 2017
1 parent 77067b2 commit 620a3c6
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
38 changes: 36 additions & 2 deletions docs/src/pages/guides/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ const DecoratedSFC = decorate<Props>(({ text, type, color, classes }) => (
));
```

Class components are a little more cumbersome. They require more type annotations, and due to a [current limitation in TypeScript's decorator support](https://github.com/Microsoft/TypeScript/issues/4881), `withStyles` can't be used as a class decorator. Instead we decorate a class component like so:
Class components are a little more cumbersome. Due to a [current limitation in TypeScript's decorator support](https://github.com/Microsoft/TypeScript/issues/4881), `withStyles` can't be used as a class decorator. Instead we decorate a class component like so:

```ts
const DecoratedClass = decorate<Props>(
const DecoratedClass = decorate(
class extends React.Component<Props & WithStyles<'root'>> {
render() {
const { text, type, color, classes } = this.props
Expand All @@ -52,3 +52,37 @@ const DecoratedClass = decorate<Props>(
}
);
```

Note that in the class example you didn't need to annotate `<Props>` in the call to `decorate`; type inference took care of everything. One caveat is that if your styled component takes _no_ additional props in addition to `classes`. The natural thing would be to write

```ts
const DecoratedNoProps = decorate(
class extends React.Component<WithStyles<'root'>> {
render() {
return (
<Typography classes={this.props.classes}>
Hello, World!
</Typography>
)
}
}
);
```

Unfortunately TypeScript infers the wrong type in this case and you'll have trouble when you go to make an element of this component. In this case you'll need to provide an explicit `{}` type argument, like so:

```ts
const DecoratedNoProps = decorate<{}>( // <-- note the type argument!
class extends React.Component<WithStyles<'root'>> {
render() {
return (
<Typography classes={this.props.classes}>
Hello, World!
</Typography>
)
}
}
);
```

To avoid worrying about this edge case it may be a good habit to always provide an explicit type argument to `decorate`.
13 changes: 13 additions & 0 deletions test/typescript/styling-comparison.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,18 @@ const DecoratedClass = decorate(
}
);

const DecoratedNoProps = decorate<{}>(
class extends React.Component<WithStyles<'root'>> {
render() {
return (
<Typography classes={this.props.classes}>
Hello, World!
</Typography>
)
}
}
);

const sfcElem = <DecoratedSFC text="Hello, World!" type="title" color="accent" />;
const classElem = <DecoratedClass text="Hello, World!" type="title" color="accent" />;
const noPropsElem = <DecoratedNoProps />;

0 comments on commit 620a3c6

Please sign in to comment.