When using the new @material-ui/styles
and @material-ui/core
together in the same project, I can successfully compile the project using the tsc
compiler.
Receiving typescript errors.
node_modules/@material-ui/core/styles/createGenerateClassName.d.ts:1:10 - error TS2305: Module '"../../../../../../../../myProject/node_modules/jss/src"' has noexported member 'GenerateClassName'.
1 import { GenerateClassName } from 'jss';
~~~~~~~~~~~~~~~~~
node_modules/@material-ui/core/styles/jssPreset.d.ts:1:10 - error TS2724: Module '"../../../../../../../../myProject/node_modules/jss/src"' has no exported member 'JSSOptions'. Did you mean 'JssOptions'?
1 import { JSSOptions } from 'jss';
~~~~~~~~~~
node_modules/@material-ui/core/styles/withStyles.d.ts:32:15 - error TS2694: Namespace '"/myProject/node_modules/jss/src/index"' has no exported member 'CreateStyleSheetOptions'.
32 extends JSS.CreateStyleSheetOptions<ClassKey> {
~~~~~~~~~~~~~~~~~~~~~~~
Found 3 errors.
I've attempted to replicate this in codesandbox and have been unable to. I think the reason for that is that it does not accurately represent a node_modules
structure...hard to tell. I believe the core of this issue is we have 2 different versions of JSS in play:
`โ yarn why jss
yarn why v1.12.0
[1/4] ๐ค Why do we have the module "jss"...?
[2/4] ๐ Initialising dependency graph...
[3/4] ๐ Finding dependency...
[4/4] ๐ก Calculating file sizes...
=> Found "[email protected]"
info Reasons this module exists
I believe since core uses one version and styles another, combined with the install()
mechanism at runtime (which TypeScript presumably cant know about since its runtime), its impossible to the new styles package alongside core.
To trigger the error, you can try to compile a file with imports like this:
import React, { FC } from 'react'
import { ThemeProvider as MuiThemeProvider } from '@material-ui/styles'
import createMuiTheme from '@material-ui/core/styles/createMuiTheme'
interface Props {
children: any
theme: any
/** The theme to apply to all children. */
}
const ThemeProvider: FC<Props> = props => {
return (
<MuiThemeProvider theme={createMuiTheme(props.theme)}>
{props.children}
</MuiThemeProvider>
)
}
export default ThemeProvider
| Tech | Version |
|--------------|---------|
| Material-UI | v3.9.0 |
| React | v16.7.0 |
| Browser | N/A |
| TypeScript | v3.2.2 |
I can successfully compile the project using the tsc compiler.
"can't" ?
Sorry I was speaking in the "expected behaviour" prose :).
I've just come across this https://sea-region.github.com/cssinjs/jss/issues/964, so actually, I think this is a JSS issue that is beyond the control of this project...unless there's some way to ignore the broken definitions?
The main problem is we are unable to override it at the project level, since TS doesn't seem to provide a way to override on a "per dependency version" basis. It could be fixable though if the definitions were overridden in the styles package itself though (I think...) though I now appreciate this is ultimately not a material-ui problem.
That's one of the issue with bundling type declarations. We correctly depend on @types/jss@9
in @material-ui/core
and jss@10
in @material-ui/styles
. Package managers don't detect the conflict and hoist jss@10
and @types/jss@9
to the root. Now typescript prefers jss@10
because it's on the same level as @types/jss@9
.
Maybe you can force your package manager to not hoist @types/jss@9
and maybe then typescript recognizes that @material-ui/core
and @material-ui/styles
use different type versions.
Another solution might be to force typescript to apply conditional path mapping. But I don't know if and how this would work.
Yeh I thought this was the case. It may be possible to force Yarn to do what you say with some hacky resolutions.
What is working for me is moving node_modules/@types/jss
(which is the version for v9) to node_modules/@material-ui/core/node_modules/@types/jss
. This way Typescript will correctly use the v9 typings for @material-ui/core
and the v10 typings for @material-ui/styles
.
You could do this with e.g. a postinstall
entry in your package.json (unix only):
"postinstall": "mkdir -p node_modules/@material-ui/core/node_modules/@types/jss && cp -r node_modules/@types/jss node_modules/@material-ui/core/node_modules/@types"
Be aware that this is heavily dependent on the package manager you use (and the node_modules/ layout).
Thanks @eps1lon. Should we close this? Feels like something we should live with until the JSS beta is published (when I imagine the @DefinitelyTyped package will be published).
Probably better for housekeeping. There are hopefully better "hacks" that create a correct node_modules/ layout. Since we started working on v4 I think that working on this issue is not very productive. Once we release v4 we should use a single styling solution.
If someone needs a node solution for the workaround:
jss-types-workaround.js
const fs = require('fs');
const path = require('path');
const copyFolderSync = (from, to) => {
fs.mkdirSync(to, { recursive: true });
fs.readdirSync(from).forEach(element => {
if (fs.lstatSync(path.join(from, element)).isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
};
copyFolderSync('node_modules/@types/jss', 'node_modules/@material-ui/core/node_modules/@types/jss');
package.json
"scripts": {
"postinstall": "node jss-types-workaround"
}
@eps1lon I'm still having this issue. Is it safe to say if we were not relying on @types/jss
before this issue, I can replace the cp
command with mv
?
I'm running into an issue where I've added onto my MUI theme with my own custom properties and they're not being recognized at run time, which I can only assume is due to @types/jss
Oh also I'm using jss-rtl, so I assume I'll have to put v9 there too
@eps1lon I'm still having this issue. Is it safe to say if we were not relying on @types/jss before this issue, I can replace the cp command with mv?
@martinmckenna This can only be answered by knowing your full dependency tree. Your question is best answered on stackoverflow since this is only an intermediate issue for some alpha version. If you have the same issue on the latest beta please open a separate issue.
Most helpful comment
What is working for me is moving
node_modules/@types/jss
(which is the version for v9) tonode_modules/@material-ui/core/node_modules/@types/jss
. This way Typescript will correctly use the v9 typings for@material-ui/core
and the v10 typings for@material-ui/styles
.You could do this with e.g. a
postinstall
entry in your package.json (unix only):Be aware that this is heavily dependent on the package manager you use (and the node_modules/ layout).