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");