Типизация компонентов

FAST Element — современная библиотека для создания веб-компонентов на базе стандарта Custom Elements и Shadow DOM. Одной из ключевых возможностей является строгая типизация свойств компонентов, что обеспечивает безопасное взаимодействие с данными и повышает читаемость кода. Типизация реализуется через сочетание возможностей TypeScript и встроенных механизмов FAST Element.

Определение свойств с типами

Свойства компонентов объявляются с использованием декоратора @attr или через статическое свойство @observable. Ключевое отличие в том, что @attr связывает свойство с атрибутом HTML, а @observable делает его наблюдаемым только внутри компонента. Типизация выполняется через TypeScript:

import { FASTElement, attr, observable } from "@microsoft/fast-element";

class MyComponent extends FASTElement {
    @attr title: string;           // Свойство связано с атрибутом HTML
    @observable count: number = 0; // Наблюдаемое свойство, не связанное с атрибутом
}

Особенности:

  • Свойства, объявленные через @attr, автоматически конвертируются из строки, полученной из атрибута, в нужный тип.
  • Свойства, объявленные через @observable, требуют явного присвоения типа, поскольку не участвуют в конвертации атрибутов.

Настройка типов атрибутов

FAST Element позволяет указывать, как свойства конвертируются из строки атрибута. Это особенно важно для чисел, булевых значений и массивов. Для этого используется attribute с настройками конвертера:

import { FASTElement, attr, html } from "@microsoft/fast-element";

const numberConverter = {
    fromAttribute(value: string | null): number {
        return value !== null ? parseFloat(value) : 0;
    },
    toAttribute(value: number): string {
        return value.toString();
    }
};

class CounterComponent extends FASTElement {
    @attr({ converter: numberConverter }) count: number = 0;
}

Ключевые моменты:

  • fromAttribute определяет преобразование атрибута в тип свойства.
  • toAttribute отвечает за обратное преобразование при обновлении DOM.
  • Это обеспечивает согласованность типов между HTML и JavaScript.

Типизация событий

FAST Element поддерживает строгую типизацию событий через интерфейсы TypeScript. Компоненты могут испускать события с определённым типом данных:

interface CounterIncrementedDetail {
    value: number;
}

class CounterComponent extends FASTElement {
    increment() {
        this.$emit<CounterIncrementedDetail>("incremented", { value: this.count });
    }
}

Особенности:

  • Метод $emit<T> гарантирует, что данные события соответствуют интерфейсу T.
  • Типизация помогает предотвратить ошибки при подписке на события и обработке event.detail.

Использование generic типов с компонентами

Для компонентов, которые работают с данными произвольного типа, FAST Element позволяет использовать generic-классы:

class ListComponent<T> extends FASTElement {
    @observable items: T[] = [];

    addItem(item: T) {
        this.items = [...this.items, item];
    }
}

Преимущества:

  • Типизация элементов массива строго соблюдается.
  • IDE и компилятор TypeScript обеспечивают автодополнение и проверку типов при работе с компонентом.

Свойства с ограниченными значениями

FAST Element поддерживает enum-подобную типизацию для свойств, что позволяет ограничивать возможные значения:

type ButtonVariant = "primary" | "secondary" | "tertiary";

class ButtonComponent extends FASTElement {
    @attr variant: ButtonVariant = "primary";
}

Эффект:

  • Любая попытка присвоить недопустимое значение будет выявлена на этапе компиляции.
  • Типизация повышает предсказуемость поведения компонентов.

Рекомендации по типизации

  1. Использовать @attr для взаимодействия с HTML атрибутами и @observable для внутренних состояний.
  2. Явно задавать типы свойств, чтобы TypeScript мог контролировать корректность данных.
  3. Использовать конвертеры атрибутов для чисел, булевых значений и массивов.
  4. Типизировать события через интерфейсы для безопасного взаимодействия между компонентами.
  5. Использовать generics для компонентов, работающих с динамическими данными.

Правильная типизация в FAST Element не только предотвращает ошибки на этапе разработки, но и упрощает поддержку больших проектов с многочисленными компонентами, обеспечивая строгую структуру данных и предсказуемое поведение.