typescript - 设置对象各个属性的函数的正确类型?
问题描述
我有一个设置对象,它有几个不同类型的不同属性。我正在尝试编写如下函数:
update(settings, name, value)
更新属性name
并将settings
其设置为value
. 我的实际用例有点不同,但这是问题的最简单版本。
我无法让 Typescript 理解我想在这里做什么,它抱怨我的代码:
interface ISettings {
string_setting: string;
boolean_setting: boolean;
}
function updateSettings(
oldSettings: ISettings,
name: keyof ISettings,
value: ISettings[keyof ISettings]
): ISettings {
let newSettings: ISettings = { ...oldSettings };
newSettings[name] = value;
return newSettings;
}
在线上
newSettings[name] = value;
我收到错误
键入'字符串 | boolean' 不能分配给类型 'never'。类型“字符串”不可分配给类型“从不”.ts(2322)
VSCode 告诉我它newSettings
属于 ISettings 类型,并且name
属于“string_setting”类型 | “布尔设置”。所以这看起来应该是这样,但仍然会引发错误。
我认为for 的类型value
也不正确,因为它只是设置对象上属性的所有可能类型的联合,它不能确保值类型与 name 参数选择的特定属性匹配。
为什么 Typescript 在我的代码中抱怨“从不”?输入我描述的函数的正确方法是什么,理想情况下如此严格以至于尝试将字符串分配给布尔设置会失败?
解决方案
翻译成简单的英文,签名
function updateSettings(
oldSettings: ISettings,
name: keyof ISettings,
value: ISettings[keyof ISettings]
)
说:
name
是一个属性的名称ISettings
value
是一个属性的值ISettings
但并没有说它在两种情况下都是相同的属性,让调用者可以自由编写:
updateSettings(isettings, "string_property", true);
...这就是为什么函数体中的属性分配不知道类型是否正确,并被编译器拒绝的原因。
相比之下,签名
updateSettings<K extends keyof ISettings>(
oldSettings: ISettings,
name: K,
value: ISettings[K]
)
表示在这样的键中只有一个类型,既是类型,又是类型。K
ISettings
name
K
value
ISettings[K]
推荐阅读
- multithreading - 如何在线程共享的简单 fifo 上通知和等待 condvar
- opengl - OpenGL 实例化绘图是否有定义的绘制顺序?
- javascript - 如何在 vue 3 中单击按钮打开新页面?
- arrays - 字典的每个值组合
- data-structures - 二叉搜索树的最小值可以不是最左边的条目吗?
- javascript - 选择机器人滚动的次数(Discord.js)
- c# - C# 图形 API 调用委托
- python - Django HTMLForms AttributeError AttributeError:模块'polls.views'没有属性'index'
- python - Python将字母转换为两位数
- r - 将具有矢量输出的函数应用于数据帧列表