TypeScript and union #1906
-
Following these docs but with a const Foo = types.model({name: types.string, foo: types.string});
const Bar = types.model({name: types.string, bar: types.string});
const FooBar = types.union(Foo, Bar)
interface IFooBar extends Instance<typeof FooBar> {} Yields:
Which I suppose makes sense. Switching to type FooBar = Instance<typeof FooBar> Maybe worth mentioning in these docs ? Going further we can give const Foo = types.model({id: types.identifier, foo: types.string, type: types.literal("foo")});
const Bar = types.model({id: types.identifier, bar: types.number, type: types.literal("bar")}); Then we can define a model: const Store = types.model({foobars: array(FooBar)})
const store = Store.create({foobars: [
{id: "1", foo:"test"}, // note omitting type here
{id: "2", bar: 200} // and here
]})
store.foobars.map(({type}) => type)
// (2) ['foo', 'bar'] ⬆️ some how it something automatically inferred Finally we can add an interface IFoo extends Instance<typeof Foo> {}
const isFoo = (foobar: FooBar): foobar is IFoo => foobar.type === "foo";
const Store = types
.model({foobars: array(FooBar)})
.views((self) => ({
get foos() { return self.foobars.filter(isFoo) }
})) Now we have: const strs = store.foos.map(({foo}) => foo) ... And: store.foos.map(({bar}) => bar) Correctly gives Comments / improvements welcome! 🙏🏻 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I edited my original post thus ⬇️, light of #1907
I'm now able to answer my question:
By 'guessing' the first model which appears to match the snapshot: mobx-state-tree/packages/mobx-state-tree/src/types/utility-types/union.ts Lines 108 to 110 in cf36cfe And as I show on #1907 this will not work if the types differ only by array properties. |
Beta Was this translation helpful? Give feedback.
I edited my original post thus ⬇️, light of #1907
const Foo = types.model({id: types.identifier, foo: types.string, type: "foo"});
const Bar = types.model({id: types.identifier, bar: types.number, type: "bar"});
const Foo = types.model({id: types.identifier, foo: types.string, type: types.literal("foo")});
const Bar = types.model({id: types.identifier, bar: types.number, type: types.literal("bar")});
I'm now able to answer my question:
By 'guessing' the first model which appears to match the snapshot:
mobx-state-tree/packages/mobx-state-tree/src/types/utility-types/union.ts
Lines 108 to 110 in cf36cfe