在 mobx 状态树中扩展模型

Extending a model in mobx state tree

我有一堆商店,每个商店都包含一个实体类型的列表,例如

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

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

有些商店可以提供额外的功能,所以我写了

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

到目前为止,一切都很好,但现在我想创建一个包含所有此类商店列表的 "store manager",但它失败了,并显示了类似

的消息

Error: [mobx-state-tree] Error while converting ...
value of type EntityStore: (id: Order)> is not assignable to type: EntityStore,
expected an instance of EntityStore or a snapshot like ... instead
(Note that a snapshot of the provided value is compatible with the targeted type)

消息很清楚,我的 "EntityStore with views" 与 "EntityStore" 不是同一类型。但它是它的扩展,所以我想知道是否有声明允许它。 Java?

中的 List<? extends EntityStore>

或者一个很好的解决方法,允许我在不更改其类型的情况下向 EntityStore 添加附加功能?

没有。你不能。因为 .views() (基本上与任何其他点方法一样)每次调用它时都会创建 a whole new ModelType 对象。

您可以改为使用 union 类型:

  • types.union(options?: { dispatcher?: (snapshot) => Type, eager?: boolean }, types...) create a union of multiple types. If the correct type cannot be inferred unambiguously from a snapshot, provide a dispatcher function to determine the type. When eager flag is set to true (default) - the first matching type will be used, if set to false the type check will pass only if exactly 1 type matches.

下面还有一个示例,说明如何 simulate inheritance by using type composition:

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)

所以,没有继承,但是,联合类型和代码重用