Использование 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,.