Current behavior:
When I add
declare module '@emotion/react' {
export {Theme} from 'somewhere';
}
typings for theme prop is correctly set, but whenever type of styled(Element) becomes StyledComponent<any, {}>. If I remove the above declaration, the type of styled(Element) becomes
StyledComponent<Props & etc>
which is correct.
Also import {ThemeProvider} from '@emotion/react'; doesn't work unless I add export {ThemeProvider} from '@emotion/react'; to the declaration.
To reproduce:
Add this declaration to your code:
declare module '@emotion/react' {
export {Theme} from 'somewhere';
}
Expected behavior:
Providing theme typing don't break other stuff.
Environment information:
react 16.12.0emotion version: 11.0.0-next.10Also happens in 11.0.0-next.11
Please provide a runnable repro case. I have very limited time lately and setting this up myself is, unfortunately, a no go - especially that I might not be able to reproduce your setting exactly 1to1 and thus might fail to repro it for some reason.
Sure, I'll prepare it soon
@Andarist Please take a look at this: https://github.com/sassanh/emotion-issue-1757-reproduction
There are two issues in this repository:
theme is of type any, Typescript doesn't report any issues. theme should be of type {color: string} because of the content of src/react-app-env.d.ts.src/App.tsx ThemeProvider is not exported from @emotion/react if I remove the content of src/react-app/env.d.ts it'll get fixed. Also if I add export {ThemeProvider} from '@emotion/react';
to that file, it'll get fixed as well.
Thanks, I will take a look at this - it might take a few days though. You could also try to investigate this on your own (or with my help) and fix the issue sooner by providing a PR with a fix.
By tracing the issue in styled-components to see how it's resolved there, I found a workaround specially by reading https://github.com/styled-components/styled-components-website/issues/447
After some trial and error I found that declaring an emotion.d.ts (or whatever) file which contains:
import '@emotion/react';
declare module '@emotion/react' {
export interface Theme {
color: string;
}
}
resolves both issues, importing @emotion/react on top of the file fixes the problem of ThemeProvider (and other exports of emotion) not being available.
And to fix theme being of type any you have to declare the theme completely in module declaration instead of declaring it in another file and import and re-exporting it here.
@sassanh Worked like a charm. Thank you!
Note that I was able to do this, reusing my actual Theme typings :
import "@emotion/react";
import { Theme as EmotionTheme } from "./styles/theme";
declare module "@emotion/react" {
export interface Theme extends EmotionTheme {}
}
Interesting - I can observe the same as you using the provided repro. I don't quite understand why this happens, I was under the impression that this would just work without importing our package inside this augmenting file.
I've prepared a PR to the docs with this included https://github.com/emotion-js/emotion/pull/1803 . Thank you for investigating this!
TypeScript files can be in one of two modes: ambient (global) or module. This almost ended up being how Node would tell the difference between script and module before they went the .mjs route instead.
When a .d.ts file is in ambient context, declare module replaces the module. When in a module, it augments it. This is documented... somewhere in the TS docs, but it sure isn't clear.
Anyway, by adding any import or export statement at root level, you can switch to module context. So, the following works, too.
export {};
declare module '@emotion/react' {
export interface Theme {
color: string;
}
}
Closing this as the appropriate change has been added to the docs some time ago already.
@threehams Thanks for the additional information, this has been quite helpful - TIL.
Most helpful comment
Interesting - I can observe the same as you using the provided repro. I don't quite understand why this happens, I was under the impression that this would just work without importing our package inside this augmenting file.
I've prepared a PR to the docs with this included https://github.com/emotion-js/emotion/pull/1803 . Thank you for investigating this!