This package generates Vue-specific TypeScript declaration files for your Custom Elements so consuming Vue projects get inline documentation, autocomplete, and type-safe validation when using your components in templates.
Types are generated from a Custom Elements Manifest (CEM) and include documentation for:
- Custom elements (types + docs)
- Attributes & properties (types + docs)
- Events (strongly typed when enabled)
- Methods (docs)
- Slots (docs)
- CSS custom properties & states (docs)
Three primary ways to generate types:
- Programmatically, from a build script
- As a plugin for the Custom Elements Manifest Analyzer
- As a plugin for
@wc-toolkit/cem-generator
npm i -D @wc-toolkit/vuejs-typesimport { generateVuejsTypes, VuejsTypesOptions } from "@wc-toolkit/vuejs-types";
import manifest from "./path/to/custom-elements.json";
const options: VuejsTypesOptions = {
/* see Configuration Options below */
};
generateVuejsTypes(manifest, options);Run the script as part of your build:
node scripts/generate-types.js// custom-elements-manifest.config.js
import { vuejsTypesPlugin } from "@wc-toolkit/vuejs-types";
export default {
plugins: [
vuejsTypesPlugin({
outdir: "./dist/types",
fileName: "custom-elements.vue.d.ts",
}),
],
};import { generateCem } from "@wc-toolkit/cem-generator";
import { vuejsTypesGeneratorPlugin } from "@wc-toolkit/vuejs-types";
generateCem({
plugins: [vuejsTypesGeneratorPlugin({ outdir: "./dist/types" })],
});There are two common ways consumers can include the generated types in their Vue projects.
Add the generated types to tsconfig.json so the compiler picks them up automatically:
{
"compilerOptions": {
"types": ["path/to/custom-elements.vue.d.ts"]
}
}Create a tiny module under src/ to ensure the file is part of the TS program (recommended for libraries):
// src/custom-elements.d.ts
import "../dist/types/custom-elements.vue.d.ts";
export {};- For Vite + Vue, add
compilerOptions.isCustomElementso the template compiler treats your custom tags as native custom elements. - Ensure the generated
.d.tsis included in the consuming project's TS program (tsconfigincludeor the module file approach above).
The Vue generator accepts a VuejsTypesOptions object to customize output.
| Option | Type | Default | What it does |
|---|---|---|---|
outdir |
string |
"./" |
Output directory for the generated .d.ts. |
fileName |
string |
"custom-element-vuejs.d.ts" |
Output file name. |
exclude |
string[] |
[] |
Exclude components by class name from the manifest. |
tagFormatter |
(tag: string) => string |
— | Rewrite tag names before emitting GlobalComponents entries. |
prefix / suffix |
string |
"" |
(Deprecated) Legacy tag rewriting; prefer tagFormatter. |
| Option | Type | Default | Notes |
|---|---|---|---|
useCemTypes |
boolean |
false |
Use types embedded in the CEM instead of ComponentClass["prop"]. Helpful for JS components + JSDoc. |
typesSrc |
string |
"type" |
Which CEM field to read when useCemTypes is on (e.g. "type" vs "parsedType"). |
componentTypePath |
(name, tag?, modulePath?) => string |
— | Override the import path used for component class types. Useful if your CEM module paths don’t match your published paths. |
globalTypePath |
string |
— | Add a global type import reference used by generated types (advanced). |
defaultExport |
boolean |
false |
If your component classes are default exports, set this so imports are generated correctly. |
Without componentTypePath, file-like component and type-reference paths from the CEM are rewritten relative to outdir. Bare package names and scoped package specifiers remain unchanged. A configured componentTypePath callback supplies the path as-is.
A declaration is treated as CSS-only when it has no named JavaScript export, has an invalid/equal-to-tag class name, or is marked with HTMLUnknownElement. The generator names its types from the tag (for example, zd-flex becomes ZdFlex), uses HTMLElement, and types attributes from their own manifest types. Bare union values such as row | column are treated as string literals. These declarations do not need a component class import, and exclude applies normally.
| Option | Type | Default | Notes |
|---|---|---|---|
stronglyTypedEvents |
boolean |
false |
Improves custom event typing (e.g. event targets, CustomEvent<detail> payloads). |
allowUnknownProps |
boolean |
false |
Loosens template checking by allowing extra attributes/props on your custom elements. |
excludeCssCustomProperties |
boolean |
false |
Skip augmenting CSSProperties with CSS custom properties from the manifest. |
| Option | Type | Default | Notes |
|---|---|---|---|
componentDescriptionOptions |
ComponentDescriptionOptions |
— | Controls how descriptions are rendered into JSDoc (used for hover docs). |
debug |
boolean |
false |
Emit contextual logs while generating. |
skip |
boolean |
false |
Skip generation (useful in CI toggles). |
overrideCustomEventType |
boolean |
— | (Deprecated) Will be removed in a future major version. |
See src/types.ts for the authoritative option definitions.
import { generateVuejsTypes } from "@wc-toolkit/vuejs-types";
import manifest from "./custom-elements.json";
generateVuejsTypes(manifest, {
fileName: "custom-elements.vue.d.ts",
outdir: "./dist/types",
stronglyTypedEvents: true,
useCemTypes: true,
tagFormatter: (tag) => tag.toLowerCase(),
});- No editor completions: confirm the consuming project's TS program includes the generated
.d.ts(module file or tsconfigtypes/include). - No hover docs on the tag: ensure your CEM includes a component
description(it is emitted as JSDoc on theGlobalComponentsentry). - Event names clobbered by native events: avoid reusing native DOM event names for custom events.
See CONTRIBUTING.md for developer instructions and guidance for automated agents.
