В Haunted, как и в других веб-компонентных библиотеках, свойства компонентов (props) играют ключевую роль в передаче данных и управлении состоянием. Правильная валидация свойств обеспечивает предсказуемое поведение компонентов, облегчает отладку и предотвращает ошибки в рантайме.
Свойства в Haunted объявляются через функцию component,
используя стандартные свойства веб-компонентов. Наиболее
распространённый способ — через объект с метаданными для каждого
свойства:
import { component, html } from 'haunted';
const MyComponent = ({ title, count }) => html`
<h1>${title}</h1>
<p>Количество: ${count}</p>
`;
MyComponent.props = {
title: { type: String, default: 'Заголовок' },
count: { type: Number, default: 0 }
};
customElements.define('my-component', component(MyComponent));
Ключевые моменты:
type задаёт ожидаемый тип свойства
(String, Number, Boolean,
Array, Object).default определяет значение по умолчанию, которое
используется при отсутствии внешнего значения.Haunted не выполняет строгую проверку типов автоматически. Для обеспечения типовой безопасности используется ручная проверка внутри компонента:
const MyComponent = ({ title, count }) => {
if (typeof title !== 'string') {
throw new TypeError(`Ожидался тип String для свойства title, получено ${typeof title}`);
}
if (typeof count !== 'number') {
throw new TypeError(`Ожидался тип Number для свойства count, получено ${typeof count}`);
}
return html`
<h1>${title}</h1>
<p>Количество: ${count}</p>
`;
};
Такой подход полезен при разработке сложных компонентов с динамическими входными данными.
Свойства можно разделить на обязательные и необязательные. В Haunted отсутствует встроенный механизм обязательности, поэтому это реализуется через проверку значения или через дефолтное значение.
MyComponent.props = {
title: { type: String },
count: { type: Number, default: 0 }
};
title здесь является обязательным — отсутствие значения
нужно проверять внутри функции компонента.count — необязательное, автоматически получает значение
0.Для проверки обязательных свойств можно использовать вспомогательную функцию:
function validateProps(props, requiredProps) {
requiredProps.forEach(prop => {
if (!(prop in props)) {
throw new Error(`Свойство "${prop}" обязательно для компонента`);
}
});
}
const MyComponent = (props) => {
validateProps(props, ['title']);
return html`<h1>${props.title}</h1>`;
};
Помимо проверки типов, часто требуется кастомная валидация, например проверка диапазонов чисел или формата строки:
const MyComponent = ({ age }) => {
if (typeof age !== 'number' || age < 0 || age > 120) {
throw new RangeError(`Возраст должен быть числом от 0 до 120, получено ${age}`);
}
return html`<p>Возраст: ${age}</p>`;
};
MyComponent.props = {
age: { type: Number }
};
Кастомные валидаторы делают компоненты более надёжными и защищают от некорректного использования.
Свойства в Haunted могут быть функциями. Их валидация сводится к
проверке типа Function:
const ButtonComponent = ({ onClick }) => html`
<button @click=${onClick}>Нажми меня</button>
`;
ButtonComponent.props = {
onClick: { type: Function }
};
typeof onClick !== 'function' помогает
избежать ошибок при попытке вызвать неопределённое свойство как
функцию.Для массивов и объектов важно не только проверить тип, но и структуру данных. Например:
const ListComponent = ({ items }) => {
if (!Array.isArray(items)) {
throw new TypeError(`Свойство "items" должно быть массивом`);
}
if (!items.every(item => typeof item === 'string')) {
throw new TypeError(`Все элементы "items" должны быть строками`);
}
return html`<ul>${items.map(i => html`<li>${i}</li>`)}</ul>`;
};
ListComponent.props = {
items: { type: Array, default: [] }
};
Это гарантирует предсказуемое отображение данных и упрощает работу с компонентом.
Для больших проектов полезно создавать вспомогательные функции или декораторы, которые автоматически проверяют типы и обязательность свойств:
function withValidation(Component, schema) {
return (props) => {
Object.entries(schema).forEach(([key, { type, required }]) => {
if (required && !(key in props)) {
throw new Error(`Свойство "${key}" обязательно`);
}
if (props[key] != null && !(props[key] instanceof type)) {
throw new TypeError(`Свойство "${key}" должно быть типа ${type.name}`);
}
});
return Component(props);
};
}
const SafeComponent = withValidation(MyComponent, {
title: { type: String, required: true },
count: { type: Number, required: false }
});
Такой подход позволяет централизованно управлять валидацией и уменьшает дублирование кода.
props с указанием типа и значения по
умолчанию для базовой безопасности.Эффективная валидация свойств в Haunted повышает стабильность компонентов, делает код более читаемым и упрощает масштабирование приложений.