2

When using [email protected] with css modules enabled and namedExports on, is there a way to wildcard import the file in Typescript and have the resulting type of each named export be a string?

// webpack.d.ts
declare module '*.module.css' {
  export = Record<string, string>; // still contains the default export.
}

Edit: Ideally, there wouldn't be a default export present on the module when importing.

1 Answer 1

2

You can't declare exports that way since they disabled arbitrary expressions here. Instead declare and type a const and export it.

declare module '*.module.css' {
  const value: Record<string, string>;
  export default value;
}

As far as I could find there is no way to have named exports declared arbitrarily. But you could just use the shorthand ambient module declaration and declare the module twice. It does mean you won't get entire type safety since this will make all named exports any but I couldn't find anything else.

declare module '*.module.css'
declare module '*.module.css' {
  // this type is from react-scripts https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/lib/react-app.d.ts
  // it is better since the data is immutable
  const classes: { readonly [key: string]: string };
  export default classes;
}

And in another file

import { someclass } from 'some.module.css';
// ^ typeof any

I believe the best solution if you really want strict type safety is to have a build-step that generates a .d.ts for all the css modules.

.SomeComponent {
  height: 10px;
}

becomes

declare const styles: {
  readonly SomeComponent: string;
};
export = styles;
Sign up to request clarification or add additional context in comments.

2 Comments

It was definitely unclear from my question, but I'm looking for named exports, not a default export of an object.
Yes, as far as I know there is no way to have arbitrarily declared named exports. They must be explicit. I believe this is the same reason interfaces cannot be arbitrarily mapped. I propose to either use shorthand module declaration merged with a regular declaration, but the type of the named exports will be any instead of string. The alternative is to use a library to generate .d.ts files based on .css files. If you don't want a default export you can export default never instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.