-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Typescript support for theme when using css prop #1197
Comments
Thank you for leaving this issue. Frustratingly, I don't know an appropriate way to apply type parameters to a pre-defined prop. (FYI, one possible way is adding some global types for theme and letting users override them, but I think this would make emotion hard to use in libraries, i.e. not appropriate.) |
@Ailrun - Do you mind expanding on why this would make emotion hard to use in libraries? I believe this is the approach styled-components took: https://www.styled-components.com/docs/api#create-a-declarations-file |
So I have just done a rather extensive work around, since I still haven't found a proper way of doing it. If there is a nice way of removing global declarations in typescript, please let me know. Dynamically remove emotion's type declaration because typescript complains otherwise. const FS = require("fs");
const Path = require("path");
const emotionFilePath = Path.join("@emotion", "core", "types", "index.d.ts");
// Obtain the possible node_modules file paths by looking at this modul and up the tree.
const paths = [...module.paths];
// Go through all paths
while (paths.length > 0) {
let path = paths.shift();
// Check if the file exists
path = Path.join(path, emotionFilePath);
if (FS.existsSync(path)) {
// Get the file
let fileContents = FS.readFileSync(path, "utf8");
// Remove the declaration (3 opening brackets followed by 3 closing brackets,
// with anything inbetween but brackets)
fileContents = fileContents.replace(
/declare global \{[^\{\}]*\{[^\{\}]*\{[^\{\}]*\}[^\{\}]*\}[^\{\}]*\}/,
""
);
// And the same with 2 brackets
fileContents = fileContents.replace(
/declare module 'react' \{[^\{\}]*\{[^\{\}]*\}[^\{\}]*\}/,
""
);
// Write the file
FS.writeFileSync(path, fileContents, "utf8");
break;
}
} Then called that "dev/removeEmotionJsxGlobal" and assigned it to postinstall in my package:
And finally declared my own typings in my index: declare module "react" {
interface DOMAttributes<T> {
css?: InterpolationWithTheme<ITheme>;
}
}
declare global {
namespace JSX {
interface IntrinsicAttributes {
css?: InterpolationWithTheme<ITheme>;
}
}
} Where ITheme is ofc my theming interface, which can be replaced by your own. I haven't tested the script on package installation, and think it might fail if modules are installed in the wrong order. I will post an update if I figured that out, but it has been enough frustration for one day in order to get this far. |
Any updates on this? |
Also curious if anyone has found a workaround for this |
My suggestion would be that the typings that add the css prop are moved into a separate package that typescript users can install if they don't care about typing the theme. |
Or do something similar to the
|
@JakeGinnivan could you take a look at this? Seems like this should be solved together with #1249 and optionally with #1507 , right? |
I think we should do something like this
Then reference To not break backwards compatibility the user should add (if they were relying on theme being an any atm)
Then in user land you add this somewhere to augment the global module.
I don't have time this week to prepare a PR for this but if someone wants to have a go, happy to help review if someone wants to give it a go. |
May I suggest you introduce this for v11 @Andarist? |
@JakeGinnivan I could be wrong, but I think your suggestion may be limiting. We use |
@joltmode sure, we plan to add this in v11 @mvestergaard this should work just like anything else, shouldnt it? Do you see any problems with doing this? declare global {
namespace Emotion {
export interface Theme extends MaterialUI.Theme { }
}
} |
@Andarist my hint about v11 was to also add this issue to the milestone. :) |
@mvestergaard I more was just throwing that out there as a suggestion. It's the one I have used so far with Express and a few other node libraries, but there may be more modern approaches as you suggest. As mentioned in the above PR, I am unsure if global can be used in babel compilation? |
@JakeGinnivan I may be wrong as mentioned. I just have some recollection of possible issues when trying to extend an interface defined in a package. So I just wanted it to be considered when this is worked on, so it isn't limited from the start. This kinda thing shouldn't have any effect on babel compilation, since babel doesn't do type checking. |
Such things can have an impact on babel compilation because Babel doesn't really know what a type is and which referenced identifiers are types and which are runtime values. It just uses a number of heuristics to determine that. I think it only matters though in the case of imports - because it needs to remove or leave a particular import so it removes everything that is not referenced as runtime value within a file. As this would be global and always referenced in type positions I think it should just work fine with Babel. |
We have decided to include a Theme interface that can be augmented in userland. This also provided that theme to the css prop - it has been implemented in #1609 and will be released in the upcoming v11. |
Dear Emotion-Js/Emotion is love.
…On Tue, Apr 12, 2022, 1:59 AM David Johnston ***@***.***> wrote:
Is there a workaround until 11 is released?
—
Reply to this email directly, view it on GitHub
<#1197 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AULAAYZHFCN7RNJB24UJM7DVEUGLTANCNFSM4GST4HKQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
emotion
version: 10.0.6react
version: 16.8.0-alpha.1Relevant code:
What you did:
Created a theme using using the
emotion-theming
packageWhat happened:
No typescript support for the provided theme object.
Reproduction:
Problem description:
From the documentation, it appears the current typescript support allows you to define the theme object shape when using
styled()
, but not when using the css prop. Currently (and as confirmed by the documentation), the object is typed asany
.Suggested solution:
Not sure if possible, but hopefully provide some way of defining a theme type via typescript generics, even when using the css prop. It appears the type is hardcoded for the css prop to
any
hereThe text was updated successfully, but these errors were encountered: