-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
Unparameterize Theme type #9295
Conversation
@pelotom Does this change anything in the docs? |
@mbrookes no, it shouldn’t. Also FYI this pertains to TypeScript only, not Flow. |
How should I create custom theme values/nodes? I could cast Theme while using it, but I don't see how can I create a custom theme the way it's mapped rigth now. I'm a typescript newbie, so any help is appreciate. I used to configure my theme this way: import {indigo} from 'material-ui/colors'
import {createMuiTheme, Theme as MuiTheme} from 'material-ui/styles'
import createPalette from 'material-ui/styles/createPalette'
interface BBoxTheme {
linkColor: string
navbar: {
title: {
fontFamily: string
}
}
bible: {
fontFamily: string
}
}
export type Theme = MuiTheme<BBoxTheme>
export default createMuiTheme<BBoxTheme>({
palette: createPalette({
primary: indigo,
type: 'light',
}),
linkColor: '#2969b0',
navbar: {
title: {
fontFamily: 'Helvetica, Arial, sans-serif',
},
},
bible: {
fontFamily: 'Lora, serif',
},
}) |
See this comment and #9272. Basically, in TypeScript there is no way to make “custom themes” type safe, so it’s best to make that clear by requiring you to cast. But also ask yourself if you really need custom themes, or could you just export your custom variables from a module and import them where needed? |
Theme as global does not work if you app runs on the server-side/isomorphic (my case) and we need to have some customization per-user. In this scenario theme as it is is really helpful. I seens to me that Theme with Parameterized type would be a better solution since it does not block you from using theme as global variable/require when suitable. It seems pretty type safe. That how I use withStyle in my project: import {StyleRules, withStyles, WithStyles} from 'material-ui/styles'
import * as React from 'react'
import {connect} from 'react-redux'
import {bindActionCreators, Dispatch} from 'redux'
import {Theme} from '../theme'
type ClassKey = 'container' | 'area' | 'menu'
const styles = (theme: Theme): StyleRules<ClassKey> => ({
container: {...},
area: {...},
menu: {...},
})
class FooterContainer extends React.PureComponent<WithStyles<ClassKey> & ConnectedProps & ActionsProps> {
...
}
export default withStyles(styles)(FooterContainer) |
What's to stop you from doing this though: const styles = (theme: Theme & { bogus: number }): StyleRules<ClassKey> => ({ that's the source of the unsafety. |
That would be fine, if I don't see how to extend theme, once I'm new to TS, any help is appreciate. |
I just added a doc to strongly type your theme through typescript module augmentation: It will get merged into the Typescript guide in the docs. |
I don't think there's a reason for
Theme
to have a type parameter. There's not really any benefit to having it currently (see #9192), and to make it useful would require making things un-type safe. I don't see the point of attaching "business variables" to a theme; one should just export one's business variables from a module, and import them in one's component modules, and everything is type safe. But if you really want to attach arbitrary variables to a theme, it's impossible to make this type safe, so we shouldn't lie and pretend it is. One can just cast the theme, e.g.