Skip to content
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

Advanced typing for classnames/bind #300

Closed
IMalyugin opened this issue Feb 6, 2023 · 4 comments
Closed

Advanced typing for classnames/bind #300

IMalyugin opened this issue Feb 6, 2023 · 4 comments

Comments

@IMalyugin
Copy link

Been looking for a way to type classnames properly for quiet some time, found a way:

Using https://www.npmjs.com/package/css-modules-typescript-loader along with advanced classnames/bind typing would let us typecheck all the bound arguments, leveling classnames/bind up to the new heights.

Would a PR with the following typing be welcome?

type StyleSheetClasses = { [name: any]: string };


/**
 * Type definition for arguments of cn (class-1, class-2, class-3)
 *   className={cn('class-1', 'class-2', { 'class-3': flag })}
 */
export type CxArgument<CL extends StyleSheetClasses> = CL | Partial<Record<CL, boolean | string | number | undefined>>;

/**
 * Type definition for cn:
 *   const cn = classnames.bind(styles)
 */
export type CxBind<CL extends StyleSheetClasses> = (...args: CxArgument<CL>[]) => string;

/**
 * Type definition for bind:
 *   import { bind } from 'classnames/bind';
 */
export type ClassNamesBind = <CL extends StyleSheetClasses>(styles: CL) => CxBind<keyof CL>;

export declare module 'classnames/bind' {
  export const bind: ClassNamesBind;
  export default {
    bind,
  };
}

Works for both strings and record:
image

@nagman
Copy link

nagman commented Mar 16, 2023

Wow, man you're a genius!
In your types definition there's no type for arrays, but I never use arrays with classnames.bind (and who does?).
So it's not perfect regarding to the features of the package, but regarding to me it's perfect, it does all what I need :)
If I encounter errors with those types I'll let you know in this thread

@nagman
Copy link

nagman commented Mar 16, 2023

And for those who are stumbling upon this thread, here's the way I solved typed css modules with classnames.bind:

  1. Install the VS Code extenstion awwit.typed-css-modules-plugin
  2. Install the typed-css-modules package within your directory (with npm or yarn, as you wish)
  3. Put // @type at the top of the css (or scss) files you want to be processed
  4. Save your css file and you should have a css.d.ts file created with all classnames exported
  5. Create a classnames.d.ts file at the root of your project (or in the src directory) with the code @IMalyugin provided
  6. And you're good to go!

I prefer installing a VS Code extension rather than a webpack plugin or a standalone script because: 1) I'm a bit afraid of changing the webpack configuration ; and 2) I already have so many scripts running in my terminal, I prefer to keep it lean.

@IMalyugin
Copy link
Author

Glad that worked out for you!

Didn't have time to integrate it ourselves, the issue with generating .d.ts too late stuttered me.
If .d.ts files are up to date - everything's great, but once new css-files are added or existing css-files are modified, we have to rely on webpack being launched, plus accept the delay.

Not sure if those are still issues using vscode extension (i'm using `JetBrains line, not even sure there is a similar extension for me). If not, it would probably have to be some IDe-integrated in-memory stylesheet type parser.

Keep us posted If you run in any issues with your setup. :)

@jonkoops
Copy link
Collaborator

This seems to overlap with #299, so I will close this as duplicate. If you think this suggestion could fix the typing issues mentioned there feel free to create a PR.

@jonkoops jonkoops marked this as a duplicate of #299 Dec 14, 2023
@jonkoops jonkoops closed this as not planned Won't fix, can't repro, duplicate, stale Dec 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants