Reputation: 112807
You can modify a MobX-state-tree node with the help of actions. This is generally great, but it can become cumbersome if you have a lot of different properties that you want to set, e.g. if you have a model representing a form.
Is there a way to write a generic action that takes a property name and a value as arguments, and sets the property to the value on the node, while still having TypeScript verify that the arguments are valid?
Example
import { types } from "mobx-state-tree";
const FormModel = types
.model({
email: "",
password: "",
username: ""
})
.actions((self) => ({
// This becomes cumbersome as the model grows
setEmail(email: string) {
self.email = email;
},
setPassword(password: string) {
self.password = password;
},
setUsername(username: string) {
self.username = username;
}
}));
Upvotes: 1
Views: 807
Reputation: 112807
As outlined by pixelkritzel in his great blogpost we can create a generic action with the help of two generic types and cast.
Example
import { cast, SnapshotIn, types } from "mobx-state-tree";
const FormModel = types
.model({
email: "",
password: "",
username: ""
})
.actions((self) => ({
set<
K extends keyof SnapshotIn<typeof self>,
T extends SnapshotIn<typeof self>
>(key: K, value: T[K]) {
self[key] = cast(value);
}
}));
const formModel = FormModel.create();
// Works!
formModel.set("email", "[email protected]");
// TypeScript gives us an error!
formModel.set("firstName", "baz");
Upvotes: 3