Mithril — это легковесный фронтенд-фреймворк для построения одностраничных приложений (SPA) с минимальным объемом кода. Его ключевые особенности — виртуальный DOM, маршрутизация и упрощённая работа с компонентами. TypeScript обеспечивает строгую типизацию и контроль над кодом, что особенно важно при масштабировании проектов.
Для начала интеграции достаточно установить пакеты:
npm install mithril
npm install --save-dev typescript @types/mithril
TypeScript автоматически использует типы из
@types/mithril, обеспечивая автодополнение и проверку
типов.
Компоненты в Mithril — это объекты с методами view и
опционально oninit, oncreate,
onupdate, onremove. С TypeScript их типизация
выглядит следующим образом:
import m, { Component, Vnode } from "mithril";
interface MyComponentAttrs {
title: string;
count?: number;
}
const MyComponent: Component<MyComponentAttrs> = {
view: ({ attrs }: Vnode<MyComponentAttrs>) => {
return m("div", [
m("h1", attrs.title),
m("p", `Count: ${attrs.count ?? 0}`)
]);
}
};
Ключевые моменты:
attrs задают типизированные свойства компонента.Vnode<MyComponentAttrs> гарантирует корректное
использование атрибутов внутри компонента.Состояние в Mithril обычно хранится внутри объекта компонента:
interface CounterState {
count: number;
}
const Counter: Component<{}> = {
oninit: (vnode) => {
(vnode.state as CounterState).count = 0;
},
view: (vnode) => {
const state = vnode.state as CounterState;
return m("div", [
m("button", {
onclick: () => state.count++
}, "Increment"),
m("span", `Count: ${state.count}`)
]);
}
};
Использование интерфейсов для состояния позволяет TypeScript отслеживать ошибки при доступе и модификации данных.
Для работы с сервером используют стандартный m.request.
Типизация данных важна для предотвращения ошибок:
interface User {
id: number;
name: string;
email: string;
}
const loadUsers = (): Promise<User[]> => {
return m.request<User[]>({
method: "GET",
url: "/api/users"
});
};
Вызов m.request<User[]> гарантирует, что
возвращаемые данные соответствуют интерфейсу User. Это
позволяет безопасно работать с массивами объектов:
loadUsers().then(users => {
users.forEach(user => console.log(user.name));
});
Mithril включает встроенный роутер. Типизация маршрутов помогает предотвратить ошибки при передаче параметров:
import m from "mithril";
interface RouteParams {
id: string;
}
const UserPage: Component<RouteParams> = {
view: ({ attrs }) => m("div", `User ID: ${attrs.id}`)
};
m.route(document.body, "/", {
"/": HomePage,
"/user/:id": UserPage
});
attrs автоматически содержит параметры маршрута с
правильными типами, что исключает ошибки при доступе к
attrs.id.
Для переиспользования логики удобно создавать функции-хуки с типами:
function useCounter(initial: number) {
let count = initial;
const increment = () => count++;
const decrement = () => count--;
return { get count() { return count }, increment, decrement };
}
const CounterHookComponent: Component = {
view: () => {
const counter = useCounter(5);
return m("div", [
m("button", { onclick: counter.decrement }, "-"),
m("span", ` ${counter.count} `),
m("button", { onclick: counter.increment }, "+")
]);
}
};
TypeScript гарантирует, что возвращаемый объект всегда будет
содержать корректные методы и геттер count.
События в Mithril также типизируются через TypeScript. Например:
const InputComponent: Component = {
view: () => m("input", {
type: "text",
oninput: (e: InputEvent) => {
const target = e.target as HTMLInputElement;
console.log(target.value);
}
})
};
Приведение e.target as HTMLInputElement позволяет
безопасно обращаться к свойствам элемента.
Mithril эффективно обновляет виртуальный DOM. С TypeScript это облегчает внедрение мемоизации и контроля типов:
const MemoComponent: Component<{ text: string }> = {
view: ({ attrs }) => m("div", attrs.text)
};
С использованием attrs TypeScript предотвращает ошибки
при изменении структуры данных, что особенно важно при больших
приложениях.
Типичный проект на Mithril с TypeScript может иметь следующую структуру:
src/
├─ components/
│ ├─ Header.ts
│ ├─ Footer.ts
│ └─ UserList.ts
├─ models/
│ └─ User.ts
├─ pages/
│ ├─ HomePage.ts
│ └─ UserPage.ts
├─ routes.ts
└─ main.ts
components/ — переиспользуемые UI-блоки.models/ — типизированные модели данных.pages/ — страницы приложения, компоненты с
роутами.routes.ts — определение маршрутов с параметрами.main.ts — точка входа, инициализация приложения.attrs, state и ответов
от API.TypeScript превращает Mithril в более предсказуемый и безопасный инструмент, сохраняя его минималистичность и высокую производительность.