学习深度对象变化处理程序在类型描述中的应用

48 阅读1分钟

类型化对象的能力是非常方便的:它让你相信你正在访问对象上的正确键,并且你正在使用这些键作为正确的类型。然而,这种类型化并不是免费的:它可能会增加诸如变化处理程序的复杂性。在这篇文章中,我们将写一个深度对象变化处理程序,它既允许我们指定深度对象类型,又能满足Typescript编译器的要求。

一个深层对象类型的例子

让我们以下面这个Settings 类型为例。它包含了一些关于我们应用程序的视觉设置和一些关于用户的信息。

type Settings = {
  display: {
    mode: 'light' | 'dark';
  };
  user: {
    name: string;
    age: number;
    admin: boolean;
  };
};

然后我们可以创建一个满足这个类型的样本对象。让我们使用下面的例子。

const settings: Settings = {
  display: {
    mode: 'dark',
  },
  user: {
    name: 'Betty',
    age: 27,
    admin: false,
  },
};

编写一个变更处理程序

那么,如果我们想要一个改变处理程序,来改变这个对象中两层深处的任何属性,该怎么办?秘密就在于对泛型的使用。我们可以指定我们的keyK 类型,其中K extends keyof Settings 。同样地,我们可以指定我们的subkey 是类型S ,其中S extends keyof Settings[K]

把这一切放在一起,我们就得到了下面的变化处理程序!

const updateSettings = <K extends keyof Settings, S extends keyof Settings[K]>(
  key: K,
  subkey: S,
  value: Settings[K][S]
): Settings => {
  const newSettings = {
    ...settings,
    [key]: {
      ...settings[key],
      [subkey]: value,
    },
  };

  return newSettings;
};

我们有了:一个框架,我们可以通过它来更新深层类型,并让我们的Typescript编译器满意