Using TypeScript
Elena is written in vanilla JavaScript with JSDoc annotations. The @elenajs/core library ships its own type declarations (dist/elena.d.ts) which are generated automatically by tsc from the JSDoc so that you get full IntelliSense and type checking.
import { Elena, html, unsafeHTML, nothing } from "@elenajs/core";For advanced typing, you can also import the utility types directly:
import type {
ElenaPropObject,
ElenaElementConstructor,
ElenaConstructor
} from "@elenajs/core";Generating types
When you build your own Elena components, @elenajs/bundler can generate TypeScript declarations for each one. Running elena build produces:
- Per-component
.d.tsfiles: A declaration file for each component (e.g.button.d.ts) with typed props and event handlers, derived from your JSDoc annotations. This lets TypeScript resolve sub-path imports like@my-lib/components/dist/button.js. custom-elements.json: The Custom Elements Manifest, a machine-readable description of your components used by IDEs and documentation tools.custom-elements.d.ts: JSX integration types that map your custom element tag names to their prop types. This enables autocomplete and type checking for<my-button variant="primary" />in JSX/TSX files.
Using the generated types
The generated custom-elements.d.ts exports a CustomElements type map. To get type checking in JSX (this works with Next.js, see further down for more examples):
// types.d.ts (in your consuming project)
import type { CustomElements } from "@my-lib/components";
type ElenaIntrinsicElements = {
[K in keyof CustomElements]: CustomElements[K] & {
onClick?: (e: MouseEvent) => void;
onFocus?: (e: FocusEvent) => void;
onBlur?: (e: FocusEvent) => void;
children?: React.ReactNode;
};
};
declare module "react" {
namespace JSX {
interface IntrinsicElements extends ElenaIntrinsicElements {}
}
}TypeScript examples
Elena provides TypeScript examples for the following JavaScript frameworks:
Authoring with TypeScript
elena build auto-detects .ts files in your source directory and transpiles them via @rollup/plugin-typescript. No extra configuration is needed: write .ts files and the bundler handles the rest.
When using TypeScript to author Elena components, you can add inline type annotations directly to your instance field declarations:
/**
* The style variant of the component.
* @property
*/
variant: "default" | "primary" | "danger" = "default";Typing static props with ElenaPropObject
When using { name, reflect } objects in static props, import ElenaPropObject to type the array:
import type { ElenaPropObject } from "@elenajs/core";
export default class Button extends Elena(HTMLElement) {
static props: (string | ElenaPropObject)[] = [
{ name: "icon", reflect: false },
];
}