SkateJS — это легковесная библиотека для создания веб-компонентов, построенная на стандартах Custom Elements. Полная интеграция с TypeScript позволяет не только обеспечить строгую типизацию, но и использовать все возможности современных IDE: автодополнение, проверку типов и безопасные рефакторинги.
Основная единица SkateJS — компонент, создаваемый через функцию
define. В TypeScript важным аспектом является корректная
типизация пропсов и слотов. Для этого используется generic-параметр при
вызове withComponent или define.
Пример базового компонента с типами:
import { define, Component, prop } from 'skatejs';
interface MyComponentProps {
title: string;
count: number;
}
class MyComponent extends Component<MyComponentProps> {
static props = {
title: prop.string(),
count: prop.number()
};
render() {
return (
<div>
<h1>{this.title}</h1>
<p>Count: {this.count}</p>
</div>
);
}
}
define('my-component', MyComponent);
Ключевые моменты:
Component<MyComponentProps> задаёт интерфейс
пропсов.prop.string() и prop.number() обеспечивают
соответствие типов в DOM-атрибутах.SkateJS поддерживает расширение компонентов через наследование. TypeScript облегчает создание базовых классов с общими пропсами и методов.
interface BaseProps {
active: boolean;
}
class BaseComponent<P extends BaseProps> extends Component<P> {
toggle() {
this.active = !this.active;
}
}
interface ButtonProps extends BaseProps {
label: string;
}
class ButtonComponent extends BaseComponent<ButtonProps> {
static props = {
...BaseComponent.props,
label: prop.string()
};
render() {
return <button>{this.label}</button>;
}
}
define('my-button', ButtonComponent);
Особенности:
<P extends BaseProps>
позволяет наследовать пропсы.props через
...BaseComponent.props сохраняет корректную типизацию.SkateJS поддерживает встроенные и пользовательские события. В TypeScript их удобно типизировать через интерфейсы для обеспечения строгой проверки параметров.
interface EventProps {
onIncrement?: (value: number) => void;
}
class CounterComponent extends Component<EventProps> {
static props = {
onIncrement: prop.callback()
};
private count = 0;
increment() {
this.count++;
if (this.onIncrement) {
this.onIncrement(this.count);
}
}
render() {
return (
<button onCl ick={() => this.increment()}>Increment</button>
);
}
}
define('counter-component', CounterComponent);
Особенности:
prop.callback() обеспечивает проверку типа
функции.this.onIncrement TypeScript проверяет
сигнатуру, предотвращая ошибки вызова.CustomEvent также
типизируется через интерфейсы:this.dispatchEvent(new CustomEvent<{ value: number }>('increment', { detail: { value: this.count } }));
SkateJS поддерживает JSX, что делает интеграцию с TypeScript
естественной. Для корректной работы необходимо настроить
tsconfig.json с "jsx": "react" или
"jsx": "react-jsx" и объявить типы для элементов
SkateJS:
declare namespace JSX {
interface IntrinsicElements {
'my-component': { title: string; count: number };
'counter-component': { onIncrement?: (value: number) => void };
}
}
После этого использование компонентов становится полностью типобезопасным:
<my-component title="Пример" count={5}></my-component>
<counter-component onIncrem ent={(val) => console.log(val)}></counter-component>
SkateJS позволяет задавать дефолтные значения пропсов через
defaultValue. В TypeScript это можно типизировать через
Partial:
interface BadgeProps {
label: string;
color?: string;
}
class BadgeComponent extends Component<BadgeProps> {
static props = {
label: prop.string(),
color: prop.string({ defaultValue: 'blue' })
};
render() {
return <span style={{ color: this.color }}>{this.label}</span>;
}
}
define('my-badge', BadgeComponent);
color становится необязательным для пользователя, но
всегда имеет значение внутри компонента.defaultValue предотвращает
ошибки undefined.SkateJS поддерживает стандартные слоты для распределения контента. В TypeScript слоты можно типизировать с помощью generic-параметров:
interface CardProps {
title: string;
}
class CardComponent extends Component<CardProps> {
static props = {
title: prop.string()
};
render() {
return (
<div class="card">
<h2>{this.title}</h2>
<slot></slot>
</div>
);
}
}
define('my-card', CardComponent);
<my-card> автоматически
рендерится в <slot>.TypeScript в SkateJS облегчает интеграцию с React, Lit или другими библиотеками, обеспечивая корректную типизацию свойств и событий:
const element = document.createElement('counter-component') as CounterComponent;
element.onIncrem ent = (value) => console.log('Incremented to', value);
document.body.appendChild(element);
as CounterComponent позволяет IDE
предлагать автодополнение для методов и пропсов.SkateJS с TypeScript создаёт полноценную среду для построения веб-компонентов с строгой проверкой типов, безопасными событиями и интеграцией с современными инструментами фронтенда. Такой подход минимизирует ошибки на этапе компиляции и улучшает поддержку кода при больших проектах.