MobX-State-Tree 中类型化的通用操作
Typed generic action in MobX-State-Tree
您可以在 actions 的帮助下修改 MobX-state-tree 节点。这通常很好,但是如果您要设置许多不同的属性,例如,它会变得很麻烦。如果你有一个代表表格的模型。
有没有办法编写一个通用操作,将 属性 名称和值作为参数,并将 属性 设置为节点上的值,同时仍然让 TypeScript 验证这些论点有效吗?
例子
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;
}
}));
As outlined by pixelkritzel in his great blogpost we can create a generic action with the help of two generic types and cast.
例子
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", "foo@bar.com");
// TypeScript gives us an error!
formModel.set("firstName", "baz");
您可以在 actions 的帮助下修改 MobX-state-tree 节点。这通常很好,但是如果您要设置许多不同的属性,例如,它会变得很麻烦。如果你有一个代表表格的模型。
有没有办法编写一个通用操作,将 属性 名称和值作为参数,并将 属性 设置为节点上的值,同时仍然让 TypeScript 验证这些论点有效吗?
例子
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;
}
}));
As outlined by pixelkritzel in his great blogpost we can create a generic action with the help of two generic types and cast.
例子
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", "foo@bar.com");
// TypeScript gives us an error!
formModel.set("firstName", "baz");