Расширение модели в дереве состояний mobx
У меня есть куча магазинов, каждый из которых содержит список одного типа объекта, как
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 с представлениями" не того типа, что и "EntityStore". Но это расширение, поэтому мне интересно, есть ли декларация, разрешающая это. Что-то вроде List<? extends EntityStore>
в Java?
Или хороший обходной путь, позволяющий мне добавить дополнительную функциональность EntityStore
без изменения его типа?
1 ответ
Нет, ты не можешь Так как .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)
Таким образом, не наследование, а объединение типов и повторное использование кода.