Stimulus изначально разработан с акцентом на простоту и минимализм, поэтому его нативная поддержка TypeScript ограничена базовой совместимостью через стандартные JavaScript модули. Основная задача при работе с TypeScript — корректная типизация контроллеров и их методов, а также использование современных возможностей языка без нарушения принципов Stimulus.
TypeScript позволяет обеспечивать строгую проверку типов при
взаимодействии с DOM и данными контроллера. Для этого требуется
настроить проект таким образом, чтобы Stimulus контроллеры писались в
.ts файлах и корректно компилировались в ES модули.
Типичный проект с Stimulus и TypeScript имеет следующую структуру:
src/
├─ controllers/
│ ├─ index.ts
│ ├─ hello_controller.ts
├─ styles/
│ └─ main.css
├─ index.ts
tsconfig.json
package.json
tsconfig.json)Для корректной работы с Stimulus рекомендуется использовать следующие настройки:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"outDir": "./dist",
"baseUrl": "./src"
},
"include": ["src/**/*"]
}
Ключевые моменты:
strict: true — включает строгую типизацию,
предотвращает ошибки на этапе компиляции.esModuleInterop: true — обеспечивает совместимость с
модулями CommonJS и ES6.moduleResolution: "Node" — позволяет TypeScript
корректно находить модули, включая Stimulus.Контроллер Stimulus представляет собой класс, наследуемый от
Controller. На TypeScript рекомендуется явно указывать типы
для свойств и методов.
Пример простого контроллера:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["output"] as const;
declare readonly outputTarget: HTMLElement;
connect(): void {
this.outputTarget.textContent = "Stimulus + TypeScript работает!";
}
greet(event: Event): void {
const button = event.currentTarget as HTMLButtonElement;
alert(`Привет, ${button.dataset.name}`);
}
}
Пояснения:
static targets = ["output"] as const; — использование
as const позволяет TypeScript корректно выводить типы для
target’ов.declare readonly outputTarget: HTMLElement; —
объявление property, соответствующего target, с указанием типа.void,
Event) повышает безопасность кода.В TypeScript обычно создается центральный файл
controllers/index.ts, который автоматически регистрирует
все контроллеры:
import { Application } from "@hotwired/stimulus";
import HelloController from "./hello_controller";
const application = Application.start();
application.register("hello", HelloController);
Можно использовать динамическую регистрацию через
import.meta.glob, если сборщик поддерживает ES-модули:
const context = import.meta.glob("./**/*_controller.ts", { eager: true });
Object.entries(context).forEach(([path, module]) => {
const name = path.match(/([^/]+)_controller\.ts$/)?.[1];
if (name && module.default) {
application.register(name, module.default);
}
});
Это позволяет автоматически подключать все контроллеры без ручного перечисления.
Stimulus предоставляет механизм data-* атрибутов. В
TypeScript рекомендуется использовать строгую типизацию при доступе к
данным:
const name = this.element.dataset.name as string;
const count = parseInt(this.element.dataset.count || "0", 10);
Использование as string или parseInt
гарантирует корректные типы и предотвращает ошибки компиляции.
Для target’ов и values можно задать собственные интерфейсы:
import { Controller } from "@hotwired/stimulus";
interface CounterValues {
count: number;
}
export default class extends Controller {
static values = { count: Number };
declare countValue: number;
increment(): void {
this.countValue += 1;
this.element.textContent = this.countValue.toString();
}
}
static values = { count: Number }; — объявление value
для контроллера.declare countValue: number; — корректная типизация
свойства.Используется стандартный сборщик, например Vite или Webpack, с поддержкой TypeScript:
Vite (vite.config.ts):
import { defineConfig } from "vite";
export default defineConfig({
root: "src",
build: {
outDir: "../dist",
rollupOptions: {
input: "index.ts"
}
}
});
Компиляция выполняется командой vite build или
tsc, в зависимости от выбранного инструмента.
Action, что
минимизирует runtime ошибки.TypeScript делает работу со Stimulus более безопасной, масштабируемой и удобной для больших проектов, позволяя сохранять минималистичную архитектуру фреймворка при строгой проверке типов и удобной интеграции с современными инструментами сборки.