css-typed v0.7.6
css-typed
TypeScript declaration generator for CSS files.
Usage
Install
Install the CLI tool as a dev dependency.
npm install --save-dev css-typedRun
Run css-typed and pass it a glob targeting your CSS files.
npx css-typed 'src/**/*.css'This will generate .d.css.ts files next to the original source files.
Note
A CSS module file with the name
foo.module.csswill emitfoo.module.d.css.ts.
Configure
Configure TypeScript to allow arbitrary extensions (TS 5+).
{
"compilerOptions": {
"allowArbitraryExtensions": true
}
}Add *.d.css.ts to your .gitignore if appropriate.
(See #4 for more information about alternative output directory.)
echo '*.d.css.ts' >> .gitignoreOptions
The following table lists the options css-typed supports.
Also run css-typed -h on the command line.
| CLI option | Default | Description |
|---|---|---|
-c or --config | Heuristics | Custom path to the configuration file. |
--localsConvention | dashesOnly | Style of exported class names. |
config
css-typed supports loading options from a configuration file instead of using command line arguments.
To load from a custom path, use the -c or --config option.
By default, css-typed looks in the following locations.
Extensionless "rc" files can have JSON or YAML format.
- Package file:
css-typedproperty inpackage.jsonorpackage.yaml - Root rc files:
.csstypedrcwith no extension or one ofjson,yaml,yml,js,cjs, ormjs - Config folder rc files:
.config/csstypedrcwith no extension or one ofjson,yaml,yml,js,cjs, ormjs - Root config files:
css-typed.configwith an extension ofjs,cjs, ormjs
Under the hood, css-typed uses lilconfig to load configuration files.
It supports YAML files via js-yaml.
See config.ts for the implementation.
localsConvention
Inspired by postcss localsConvention.
Adds none option value to use the class name as-is.
The --localsConvention option changes the style of exported class names, the exports in your TS (i.e., the JS names).
css-typed will only camelize dashes in class names by default (the dashesOnly option value).
It will not preserve the original class name.
For example, my-class becomes myClass and you cannot use my-class in JS/TS code.
Modern bundlers or build system such as Vite and Gatsby support this transformation.
The default matches CSS naming practices (kebab-case).
IMPORTANT
Note that
camelCaseanddashesMAY have TypeScript bugs. TypeScript 5.6 may help with the named exports for these.If you encounter a bug, please file an issue. In the mean-time, consider using
camelCaseOnlyinstead. (OrdashesOnlywhich is the default.)
Recipes
Run script
To run it as part of your build, you will likely include it as a run script, maybe as codegen or pretsc.
{
"scripts": {
"codegen": "css-typed \"src/**/*.css\"",
"pretsc": "css-typed \"src/**/*.css\"",
"tsc": "tsc"
}
}Watch
The CLI does not have built-in watch support. Feel free to nodemon or similar.
{
"scripts": {
"codegen": "css-typed \"src/**/*.css\"",
"codegen:watch": "nodemon -x \"npm run codegen\" -w src -e css"
}
}Motivation
typescript-plugin-css-modules provides a great IDE experience, but cannot perform build-failing type-checking.
Furthermore, the traditional TypeScript ambient module definition fails the noUncheckedIndexedAccess strict check and causes issues with typed ESLint rules.
// This does not provide strict typing
declare module "*.module.css" {
const classes: { [key: string]: string };
export default classes; // It also uses default export šæ
}typed-css-modules and typed-scss-modules exist, but the former does not have recent activity and the latter focuses on SCSS. (My current (2023/2024) interests involve modern CSS only.) Both depend on css-modules-loader-core, which appears abandoned.
Therefore, I wrote my own (very basic) implementation. See §Implementation details for more information.
Contributing
See CONTRIBUTING.md.
Implementation details
This (very basic) implementation uses glob for file matching and css-tree for CSS parsing.
It extracts CSS classes (ClassSelector in CSS Treeās AST) and exports them as string constants (named exports).
The CSS-file class name is modified for JS export according to the localsConvention option. The implementation matches PostCSS.
I chose CSS Tree after a brief search because it had a nice API, good documentation, and supported CSS nesting (a requirement for my original use case).
css-typed uses Commander.js for command line parsing and lilconfig for configuration file loading.
The ābrandā image/logo combines the public CSS 3 and TypeScript logos with a basic plus icon in between. See css-typed.svg.
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago