typescript - 如何避免 TypeScript 中的动态 keyof 对象分配错误
问题描述
假设我们的 TypeScript 代码如下所示:
type User = {
id: number,
name: string,
}
let user1: User = {id: 123, name: "Hello"};
let user2: User = {id: 456, name: "World"};
let keys: (keyof User)[] = ["id", "name"];
for (let key of keys) {
user1[key] = user2[key];
}
这给出了错误
Type 'string | number' is not assignable to type 'never'.
对于声明
user1[key] = user2[key];
如果我们改变keys
to的定义
let keys: string[] = ["id", "name"];
错误消失了,但我们失去了类型安全。
有什么方法可以避免这个错误,同时仍然保持类型安全?
解决方案
这里没有避免类型断言的好方法。在 TS 的最新版本(我认为是 3.5 后)中,当通过索引写入时,写入的值必须与键指定的所有可能的属性值兼容。在您的情况下,这将number & string
减少never
因此错误。
根本原因是 TS 不会仅跟踪类型的变量,因此就类型而言,您的示例与以下内容没有什么不同:
let key1 = 'id' as keyof User;
let key2 = 'name' as keyof User;
//Obvious error
user1[key1] = user2[key2] // same error, TS can't distingusih between this and your user1[key] = user2[key]
最简单的解决方案是使用类型断言,如果在您的情况下您确定这是可以的:
type User = {
id: number,
name: string,
}
let user1: User = { id: 123, name: "Hello" };
let user2: User = { id: 456, name: "World" };
for (let key of keys) {
user1[key] = user2[key] as never
}
或者(但不再是类型安全的)您可以使用一个T[K]
可分配给索引值的小漏洞:
type User = {
id: number,
name: string,
}
let user1: User = { id: 123, name: "Hello" };
let user2: User = { id: 456, name: "World" };
let keys: (keyof User)[] = ["id", "name"];
for (let key of keys) {
set(user1, key, user2[key])
}
推荐阅读
- cordova - 在 Cordova 上访问浏览器 DevTools
- sql - Redshift UNLOAD 连接文件名
- c# - 使用 .NET 4.5 或更高版本从 Outlook 拖放 C#
- java - 根据设备的大小在 Android 中调整表单大小
- elasticsearch - 使用 Elasticsearch 中的排序按查询删除
- sql - Pl/Sql 中的 XmlType
- node.js - 如果项目不存在,则将项目添加到数组中 mongodb
- python-3.x - 通过计算数组中的字符串并从数组中添加它们的值来填充熊猫数据框
- jquery - 随机列表组合和顺序
- oracle - 是否可以在不同数据库中的表之间进行连接?