`babel-plugin-react-css-modules` Typescript Type Checking

1.3k views Asked by At

I am using babel-plugin-react-css-modules. It add the styleName property to HTML elements. Typescript doesn't recognize this property. I am pretty sure I need to extend something but nothing I have tried has worked.

I have tried declaring an Element in a '.d.ts' file to do declaration merging but I must be doing something wrong.

interface Element {
    styleName: string;
}

export const Wrapper: React.FC<IWrapperProps> = ({ children, style }) => (
  <div styleName="wrapper" style={style}>
    {children}
  </div>
);

UPDATE:

.d.ts not working

3

There are 3 answers

0
Daniel Rosenwasser On

Since you're in a module (it has an export), you're working with a separate scope from the global scope - so you're just creating an interface named Element that's separate from the global declaration.

I'd place the interface in a separate file with no exports/imports (augmentations.d.ts) and add that to your tsconfig.json.

0
Alexander van Oostenrijk On

Add @types/react-css-modules to your package.json and styleName will be recognized:

npm install @types/react-css-modules --save-dev
0
Tom On

Best option:

  1. use babel-loader with babel-plugin-react-css-modules plugin, followed by 'ts-loader' (note the loaders are run in reverse order)

webpack config for this looks something like:

{
          test: /\.tsx?/,
          exclude: '/node_modules/',
          use: [
            { loader: 'ts-loader' },
            {
              loader: 'babel-loader',
              options: {
                babelrc: false,
                "plugins": [
                  ["@babel/plugin-syntax-typescript",
                {
                  isTSX: true
                }],
                  "@babel/plugin-syntax-jsx",
                  [
                    "babel-plugin-react-css-modules",
                    {
                      "handleMissingStyleName": "throw"
                    }
                  ]
                ]
              }
            },
          ]
        }

Excluding babelrc as babel if being used to compile .js files they mustn't interfere with the typescript compile.

  • babel-loader runs first, process styleName props but leaves the typescript as it is.

  • ts-loader then runs, type checking and transpiling the typescript.

Alternative Less good option.

  1. don't use ts-loader to compile .ts[x] files. This works but means you don't get compile time type checking. (which kind of defeats the point of using ts over js)