skovy / typed-scss-modules

🎁 Generate type definitions (.d.ts) for CSS Modules using SCSS
https://skovy.dev/generating-typescript-definitions-for-css-modules-using-sass/
MIT License
638 stars 67 forks source link

Don't generate TypeScript definitions for classes imported with `@use` #210

Open simensol opened 1 year ago

simensol commented 1 year ago

I'm using the Vuetify library which ships with a lot of utility classes. I'm @extend some of these classes in my own classes, e.g.:

@use "vuetify/styles";

.my-text-class {
    // Extend Vuetify's .text-wrap class:
    @extend .text-wrap;

    hyphens: none;
}

When I generate TypeScript definitions for this SCSS module, it also generate types for all the 4000+ Vuetify classes imported with @use "vuetify/styles":

export type Styles = {
  align_baseline: string;
  align_center: string;
  align_content_center: string;
  align_content_end: string;
  align_content_lg_center: string;
  align_content_lg_end: string;
  align_content_lg_space_around: string;
  ...
  my_text_class: string;
  ...
  w_100: string;
  w_25: string;
  w_33: string;
  w_50: string;
  w_66: string;
  w_75: string;
  w_auto: string;
};

export type ClassName = keyof Styles;

declare const styles: Styles;

export default styles;

Is there a way to make typed-scss-modules generate TypeScript definitions for my own classes only?

GeorgeTaveras1231 commented 1 year ago

The way this tool works is it compiles with sass and determines which classes are defined after the fact.

One solution would be to provide a custom importer that returns an empty file for certain sass imports.

This will work but I think its error prone because you'll have to maintain an explicit list of the imports you want to omit, and if your file has an hard dependency on any imported values, it cause a build error.

My recommendation is to accept the lost of type specificity here, or do a manual Omit with ts on your code.

simensol commented 1 year ago

What about implementing a comment which determines sources to exclude, e.g.:

@use "settings";
@use "vuetify/styles"; // typed: ignore

...

Then you don't have to maintain a separate file.

skovy commented 1 year ago

Thanks for opening the issue. That's an interesting use case.

I like @GeorgeTaveras1231 recommendation of using an importer. Here are the docs on it: https://github.com/skovy/typed-scss-modules#importer

This should allow you to check for this specific import and return nothing, but could lead to other issues.

The special comment is interesting, but I'm guessing it could lead to complexity implementing/supporting it that would likely be a customer importer under-the-hood.