Использование TypeScript¶
Поскольку XState написан на TypeScript, строгая типизация диаграмм состояний полезна и приветствуется. Рассмотрим пример простого автомата:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
Предоставление контекста и событий в качестве общих параметров для функции createMachine()
дает множество преимуществ:
- Тип / интерфейс контекста (
TContext
) передается действиям, защитным функциям, службам и многому другому. Он также передается в глубоко вложенные состояния. - Тип события (
TEvent
) гарантирует, что в конфигурациях перехода используются только указанные события (и встроенные, специфичные для XState). Предоставленные формы объекта события также передаются действиям, защитным функциям и службам. - События, которые вы отправляете в автомат, будут строго типизированы, что даст вам гораздо больше уверенности в формах полезной нагрузки, которые вы будете получать.
Объекты настроек¶
Общие типы для MachineConfig<TContext, any, TEvent>
такие же, как и для createMachine<TContext, TEvent>
. Это полезно, когда вы определяете объект конфигурации автомата вне функции createMachine(...)
, и помогает предотвратить ошибки вывода типов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Типизированные состояния¶
Начиная с версии 4.7+
Типизированные состояния (Typestates) — это концепция, сужающая форму общего контекста состояния context
на основе значения состояния value
. Это может быть полезно для предотвращения невозможных состояний и сужения контекста context
, который должен быть в данном состоянии, без необходимости писать лишние утверждения.
Typestate
— это интерфейс, состоящий из двух свойств:
value
— значение состояния typestate (на составные состояния следует ссылаться с использованием синтаксиса объекта; например,{idle: 'error'}
вместоidle.error
)context
— суженный контекст состояния типа, когда состояние соответствует заданномуvalue
Типизированные состояния автомата указываются как 3-й общий тип в createMachine<TContext, TEvent, TTypestate>
.
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
Внимание
Для составных состояний все значения родительских состояний должны быть явно смоделированы, чтобы избежать ошибок типа при тестировании подсостояний.
1 2 3 4 5 6 7 8 9 10 11 |
|
Если два состояния имеют одинаковые типы контекста, их объявления могут быть объединены с помощью объединения типов для значения.
1 2 3 4 5 6 7 |
|
Исправление проблем¶
У XState и TypeScript есть некоторые известные ограничения. Нам нравится TypeScript, и мы постоянно работаем над тем, чтобы сделать его лучше в XState.
Вот некоторые известные проблемы, которые можно обойти:
События в опциях автомата¶
Когда вы используете createMachine
, вы можете передавать реализации именованным действиям / службам / защитным функциям в вашем config
. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Причина этих ошибок в том, что внутри функции consoleLogData
мы не знаем, какое событие вызвало ее срабатывание. Самый простой способ справиться с этим — самостоятельно подтвердить тип события.
1 2 3 4 5 6 7 8 9 |
|
Также иногда возможно переместить реализацию внутрь.
1 2 3 4 5 6 7 8 9 10 11 |
|
Этот подход работает не во всех случаях. Действие теряет свое название, поэтому на него становится менее приятно смотреть в визуализаторе. Это также означает, что если действие дублируется в нескольких местах, вам нужно скопировать и вставить его во все необходимые места.
Типы событий в действиях входа¶
Типы событий во встроенных входных действиях в настоящее время не относятся к событию, которое к ним привело. Рассмотрим этот пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Здесь мы не знаем, какое событие привело к действию entry
в state2
. Единственный способ исправить это — проделать аналогичный трюк, описанный выше:
1 2 3 4 5 6 7 |
|
onDone
и onError
события в настройках автомата¶
Результат использования служб на основе промисов довольно сложно безопасно ввести в XState. Например, такой автомат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
К сожалению, лучший способ исправить это — передать event
в any
и переназначить его в зависимости от того, что мы знаем о нем:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Странное поведение действия assing¶
При запуске в режиме strict: true
действия assign
иногда могут вести себя очень странно.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Может показаться, что ничего из того, что вы пытаетесь сделать, не работает — все синтаксисы ошибочны. Исправление очень странное, но работает стабильно. Добавьте неиспользуемый аргумент контекста context
к первому аргументу функции assign
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Это неприятная ошибка, которую нужно исправить, и она включает в себя перевод нашей кодовой базы в строгий режим, но мы планируем сделать это в V5.
keyofStringsOnly
¶
Если вы видите эту ошибку:
1 2 |
|
Убедитесь, что ваш файл tsconfig
не включает "keyofStringsOnly": true,
.