Description
Prerequisites
- I have read the Contributing Guidelines.
- I agree to follow the Code of Conduct.
- I have searched for existing issues that already report this problem, without success.
Stencil Version
4.27.2
Current Behavior
Bug Ticket
Description
The Stencil compiler generates a components.d.ts
file that defines component interfaces using camelCase property names in the Components
namespace, but fails to include kebab-case alternatives in the HTML element interfaces. This causes type errors when using the web components in React or other frameworks that use kebab-case attribute names in JSX.
Current Behavior
Currently, the generated components.d.ts
file:
-
Defines component properties in camelCase within the
Components
namespace:export namespace Components { interface MdxProductCard { "availability"?: "available" | "unavailable" | "disabled"; "brand"?: string; "discountPrice"?: number; // other properties... } }
-
HTML element interfaces extend the Components interfaces:
interface HTMLMdxProductCardElement extends Components.MdxProductCard, HTMLStencilElement { // event listeners... }
-
The React and Stencil JSX typings need to be manually added with a custom script to support kebab-case attributes:
declare module "react" { export namespace JSX { interface IntrinsicElements { "mdx-product-card": { "discount-price"?: number | string; "discountPrice"?: number | string; // other properties... }; } } }
Expected Behavior
Expected Behavior
The Stencil compiler should automatically generate HTML element interfaces that support both camelCase and kebab-case property names:
-
The
Components
namespace should continue to use camelCase for TypeScript usage. -
The HTML element interfaces should support both camelCase and kebab-case attributes:
interface HTMLMdxProductCardElement extends Components.MdxProductCard, HTMLStencilElement { // Add support for kebab-case attributes "discount-price"?: number; // existing camelCase properties from Components.MdxProductCard // event listeners... }
-
The React and Stencil JSX typings should be automatically generated with both camelCase and kebab-case attributes.
System Info
Steps to Reproduce
Steps to Reproduce
-
Create a Stencil component with camelCase properties:
@Component({ tag: "my-component" }) export class MyComponent { @Prop() discountPrice: number; }
-
Build the component library with
stencil build
-
Examine the generated
components.d.ts
file -
Try to use the component in React with kebab-case attributes:
<my-component discount-price={5} />
-
Observe TypeScript errors because the kebab-case attribute is not defined in the typings.
Code Reproduction URL
https://github.com/BenjaminBrossi/stencil-typings
Additional Information
Impact
This issue forces teams to create and maintain custom scripts to generate proper typings for React and other frameworks. Without these scripts, developers experience type errors when using kebab-case attributes in JSX, even though the web components themselves accept these attributes at runtime.
Environment
- Stencil version: 4.27.2
- TypeScript version: 5.7.3
- React version: 19
Workaround
We currently use a custom script to generate proper typings for React and Stencil JSX. This script:
- Extracts all component properties from the generated
components.d.ts
- Converts camelCase properties to kebab-case
- Generates React and Stencil JSX module declarations with both camelCase and kebab-case properties
- Appends these declarations to the
components.d.ts
file
This workaround is maintenance-intensive and should be unnecessary if Stencil properly supported kebab-case attributes in its generated typings.