Расширение модели в дереве состояний mobx - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть несколько магазинов, каждый из которых содержит список одного типа сущностей, например

const userStore = EntityStore.create(....)

const supplierStore = EntityStore.create(....)

Некоторые магазины могут предлагать дополнительные функции, поэтому я написал

const orderStore = EntityStore
.views(self => ({
    allByUserId: branchId => ....)
}))
.create(....)

Пока что всебыло хорошо, но теперь я хотел создать «менеджер магазина», содержащий список всех таких магазинов, и это не удалось с сообщением типа

Ошибка: [mobx-state-tree] Ошибка при преобразовании...
значение типа EntityStore: (id: Order)> нельзя назначить типу: EntityStore,
ожидал экземпляр EntityStore или снимок, подобный ... вместо
(Обратите внимание, чтоснимок предоставленного значения совместим с целевым типом)

Сообщение ясно, мой "EntityStore with views" не относится к типу "EntityStore".Но это расширение, поэтому мне интересно, есть ли декларация, разрешающая это.Что-то вроде List<? extends EntityStore> в Java?

Или хороший обходной путь, позволяющий мне добавить дополнительные функции к EntityStore без изменения его типа?

1 Ответ

0 голосов
/ 02 марта 2019

Нет.Ты не можешьПотому что .views() (как и любой другой метод точек) создает новый объект ModelType каждый раз, когда вы вызываете его.

Вместо этого вы можете использовать тип union:

  • types.union(options?: { dispatcher?: (snapshot) => Type, eager?: boolean }, types...) создать объединение нескольких типов.Если правильный тип не может быть однозначно выведен из снимка, предоставьте функцию диспетчера для определения типа.Когда eager flag установлен в true (по умолчанию) - будет использоваться первый соответствующий тип, если в false установлено, проверка типа пройдет только при совпадении ровно 1 типа.

Также имеетсяПриведенный ниже пример того, как имитировать наследование, используя композицию типов :

const Square = types
    .model(
        "Square",
        {
            width: types.number
        }
    )
    .views(self => ({
        surface() {
            return self.width * self.width
        }
    }))

// create a new type, based on Square
const Box = Square
    .named("Box")
    .views(self => {
        // save the base implementation of surface
        const superSurface = self.surface

        return {
            // super contrived override example!
            surface() {
                return superSurface() * 1
            },
            volume() {
                return self.surface * self.width
            }
        }
    }))

// no inheritance, but, union types and code reuse
const Shape = types.union(Box, Square)

Итак, нет наследования, но типы объединения и повторное использование кода .

...