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-typed
Run
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.css
will 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' >> .gitignore
Options
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-typed
property inpackage.json
orpackage.yaml
- Root rc files:
.csstypedrc
with no extension or one ofjson
,yaml
,yml
,js
,cjs
, ormjs
- Config folder rc files:
.config/csstypedrc
with no extension or one ofjson
,yaml
,yml
,js
,cjs
, ormjs
- Root config files:
css-typed.config
with 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
camelCase
anddashes
MAY 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
camelCaseOnly
instead. (OrdashesOnly
which 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.
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago