В последние недели ImmutableJS был привлечен к FRP и особенно к Cycle.js, и он казался находкой для управления состоянием, поскольку изменяемое состояние, по крайней мере, по мнению некоторых, является корнем всего зла. В Cycle.js ваше приложение представляет собой чистую функцию, которая принимает взаимодействие с пользователем в качестве входных данных и предоставляет пользовательский интерфейс в качестве выходных данных, без побочных эффектов. Написание чистой функции без побочных эффектов также означает, что вы не можете удерживать какое-либо состояние как таковое. Как же тогда вы управляете состоянием своего приложения?

В Cycle.js все, что изменяется, моделируется как поток, и зачем делать исключение для состояния? Теперь мы реагируем на состояние $ (читайте поток состояния), которое само может реагировать на другие потоки. У нас есть состояние $, представляющее изменяющееся состояние, поэтому у нас также не может быть мутирующего состояния - это просто вызывает большую путаницу в том, что составляет изменение состояния в приложении, а что нет. Кроме того, наличие потока неизменяемых состояний, которые можно сворачивать (агрегировать) в коллекцию, дает нам всю историю, позволяя нам путешествовать во времени.

Решение хорошее, но как реализовать неизменяемость и убедиться, что все работает? Здесь и появился ImmutableJS. Это библиотека, которая позволяет вам работать с Immutables. Подумайте о неизменяемых объектах, коллекциях и т. Д. Однако есть одна большая проблема. Вы используете строковые методы получения и установки свойств.

Когда вы работаете с TypeScript в прекрасном редакторе, таком как Visual Studio Code, проверка статического типа творит чудеса. (Если не пробовали, стоит. Серьезно.) Но при использовании Map или fromJs все вылетает окно. У вас больше нет проверок типов, все возвращается к ужасному. Проблема с любым из них заключается в том, что оно распространяется по вашему приложению, пока все, что вы используете, не будет отображаться как любое и больше не будет никакой полезной проверки статического типа.

Обходной путь - добавлять типы к каждой используемой константе, но кто, черт возьми, это делает? Кроме того, если вам нужно указывать тип каждый раз, когда вы что-то используете, зачем вообще использовать TypeScript (хотя он работает)? Мы хотим собственности. И нам нужны средства получения свойств с именами вместо использования функции со строками. На очереди Запись, которая пытается вас спасти. С помощью записи вы можете указать разрешенные ключи и получить прямой доступ к исходным ключам.

Все, что вам нужно сделать, это определить интерфейс для вашего типа, создать запись, а затем расширить запись с помощью вашего класса, реализующего интерфейс. Скажем, я хочу иметь интерфейс для человека. Я бы назвал его IPerson (чтобы у меня был класс Person) и определил свойства там. Я бы создал PersonRecord со значениями по умолчанию. Затем я бы создал класс Person, который расширяет PersonRecord и реализует IPerson.

Есть еще одна проблема - конструктор принимает любой объект с любыми свойствами. Давай изменим это. Задайте тип параметра конструктора IPerson. Задача решена! Теперь у вас есть типизированный неизменяемый объект, у которого есть методы получения на основе свойств (не установщики).

ПРИМЕЧАНИЕ: Руководство по стилю TypeScript рекомендует называть интерфейсы без начального I. Однако я считаю, что это реальный случай, когда его можно использовать. Строгие последователи руководства по стилю могут вместо этого использовать PersonBase в качестве имени интерфейса.

Это сработало для вас? Мог бы я сделать что-нибудь лучше? Я что-то упустил? Пожалуйста, используйте комментарии, чтобы разместить свои отзывы, предложения и все, чем вы хотите поделиться.

Ваше здоровье!