Typed props

Atomico — библиотека для создания веб-компонентов на основе реактивной модели, предоставляющая мощный инструмент для типизации свойств компонентов. Typed props позволяют строго определить типы входных данных, что улучшает безопасность кода, автодополнение в редакторах и упрощает поддержку крупных приложений.

Определение typed props

Typed props создаются с использованием функции prop. Основная задача — задать тип, значение по умолчанию и, при необходимости, валидатор.

import { c, prop } from "atomico";

function MyComponent({ title, count }) {
    return (
        <host>
            <h1>{title}</h1>
            <p>Count: {count}</p>
        </host>
    );
}

MyComponent.props = {
    title: prop.string({ default: "Заголовок" }),
    count: prop.number({ default: 0 })
};

export const myComponent = c(MyComponent);

В примере выше:

  • prop.string определяет, что title обязательно строка.
  • prop.number гарантирует числовое значение для count.
  • default задаёт значение по умолчанию, если проп не передан.

Типы props

Atomico поддерживает несколько базовых типов:

  • string — строка
  • number — число
  • boolean — логическое значение
  • array — массив
  • object — объект
  • any — любой тип

Примеры с разными типами:

MyComponent.props = {
    title: prop.string({ default: "Hello" }),
    isActive: prop.boolean({ default: true }),
    items: prop.array({ default: [] }),
    config: prop.object({ default: {} }),
    data: prop.any()
};

Использование any рекомендуется только при полной неопределенности типа, так как оно отключает проверки.

Валидаторы props

Для более строгого контроля можно использовать кастомные валидаторы через опцию validate.

MyComponent.props = {
    count: prop.number({
        default: 0,
        validate: value => value >= 0
    })
};

Здесь любое отрицательное значение count будет игнорироваться, что защищает компонент от некорректных данных.

Комплексные типы

Typed props поддерживают композицию типов:

  • oneOf — выбор из фиксированного набора значений
  • instanceOf — проверка на экземпляр класса
MyComponent.props = {
    size: prop.oneOf(["small", "medium", "large"], { default: "medium" }),
    date: prop.instanceOf(Date)
};
  • oneOf позволяет ограничить значения заранее определённым списком.
  • instanceOf проверяет принадлежность объекта к определённому классу.

Реактивность typed props

Props в Atomico автоматически реактивны. Любое изменение значения триггерит перерендер компонента.

function Counter({ count }) {
    return <host>{count}</host>;
}

Counter.props = {
    count: prop.number({ default: 0 })
};

const counter = c(Counter);

Если родительский компонент обновляет count, компонент Counter обновится автоматически.

Интеграция с TypeScript

Typed props интегрируются с TypeScript, что позволяет использовать строгую типизацию на уровне кода:

interface MyProps {
    title: string;
    count: number;
}

function MyComponent({ title, count }: MyProps) {
    return (
        <host>
            <h1>{title}</h1>
            <p>{count}</p>
        </host>
    );
}

Совмещение с prop обеспечивает:

  • статическую проверку типов
  • автодополнение
  • безопасность при передаче данных между компонентами

Динамические и вычисляемые значения

Props могут иметь вычисляемое значение через функцию:

MyComponent.props = {
    greeting: prop.string({
        default: ({ title }) => `Привет, ${title}!`
    })
};

Функция получает текущие значения других props, что позволяет создавать динамические зависимости внутри компонента.

Работа с массивами и объектами

Для массивов и объектов можно задать типизацию элементов или свойств:

MyComponent.props = {
    items: prop.array({
        default: [],
        validate: arr => arr.every(item => typeof item === "string")
    }),
    config: prop.object({
        default: {},
        validate: obj => "url" in obj
    })
};
  • Проверка массива через every гарантирует, что все элементы соответствуют типу.
  • Проверка объекта через in или любые другие условия контролирует структуру данных.

Обработка необязательных props

Props могут быть необязательными:

MyComponent.props = {
    optionalText: prop.string()
};

Если optionalText не передан, компонент получит undefined. При этом можно задать значение по умолчанию, чтобы избежать ошибок.

Комбинация с слотовыми компонентами

Typed props органично работают вместе со слотами:

function Card({ title }, { slots }) {
    return (
        <host>
            <h2>{title}</h2>
            <div>{slots.default}</div>
        </host>
    );
}

Card.props = {
    title: prop.string()
};

Props управляют состоянием и логикой компонента, а слоты — его содержимым, что создаёт гибкие и переиспользуемые UI-блоки.

Typed props в Atomico обеспечивают строгую, безопасную и удобную систему работы с данными компонентов, поддерживая реактивность, интеграцию с TypeScript и сложные сценарии валидации. Они являются ядром современного подхода к веб-компонентам с высокой предсказуемостью поведения и удобством поддержки больших приложений.