类型化对象的能力是非常方便的:它让你相信你正在访问对象上的正确键,并且你正在使用这些键作为正确的类型。然而,这种类型化并不是免费的:它可能会增加诸如变化处理程序的复杂性。在这篇文章中,我们将写一个深度对象变化处理程序,它既允许我们指定深度对象类型,又能满足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,
},
};
编写一个变更处理程序
那么,如果我们想要一个改变处理程序,来改变这个对象中两层深处的任何属性,该怎么办?秘密就在于对泛型的使用。我们可以指定我们的key 是K 类型,其中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编译器满意