在 Javascript 和 Typescript 中,我们经常遇到这样的情况:我们有一个具有一组属性的对象,然后是另一个与该对象中的一个或多个键匹配的变量。如果可以编辑键,这可能会导致各种问题。例如,想象以下情况:
let myUser = {
name: "John Doe",
email: "xyz@code8cn.com",
age: 15
}
function getUserDetails() {
let ourKeys = [ "name", "red", "age" ];
let constructedObject = {};
ourKeys.forEach(function(item) {
constructedObject[item] = myUser[item];
});
return constructedObject
}
我们可以想象它ourKeys
可能来自数据库或 API。为了解释的目的,我把它放在一个简单的数组中。当我们使用forEach
循环遍历这些键中的每一个时,我们将详细信息输出myUser
到一个名为 的新对象中constructedObject
。
唯一的问题是它red
不是一键输入myUser
,而是一键输入ourKeys
。理想情况下, in 中的键ourKeys
应与 中的键匹配myUser
。
使用 keyof 解决不匹配的键#
为了解决上述问题,我们使用keyof
. 让我们在Typescript中重新构想我们的代码。
自定义类型
今天我们将使用自定义类型。如果您不熟悉它们,请在此处阅读我们的 Typescript 自定义类型指南。
首先,让我们给我们的myUser
对象一个自定义类型:
type User = {
name: string,
email: string,
age: 15
}
let myUser:User = {
name: "John Doe",
email: "xyz@code8cn.com",
age: 15
}
现在,让我们为ourKeys
. 本质上,我们想要ourKeys
成为或。我们可以定义它的一种方法是:name
email
age
type UserKeys = "name" | "email" | "age"
这在理论上是可行的,但不一定是完全证明——如果User
类型改变了,而我们忘记了更新UserKeys
怎么办?我们会遇到一些问题。相反,我们可以像这样写上面的行,这意味着完全相同的事情:
type UserKeys = keyof User
这意味着UserKeys
是一种转换为"name" | "email" | "age"
– 但将始终与User
. 现在我们已经构建了我们的类型,让我们更新我们的代码:
type User = {
name: string,
email: string,
age: number
}
type UserKeys = keyof User
let myUser:User = {
name: "John Doe",
email: "xyz@code8cn.com",
age: 15
}
function getUserDetails() {
let ourKeys:UserKeys[] = [ "name", "email", "age" ];
let constructedObject:Partial<user> = {};
ourKeys.forEach(function<k extends="" UserKeys="">(item:K) {
if(typeof myUser[item] !== "undefined") {
constructedObject[item] = myUser[item];
}
});
return constructedObject
}
</k></user>
现在如果ourKeys
包含“red”,我们会得到一个错误 – 所以它应该总是注册正确的键。如您所见,keyof
这让我们编写 Typescript 变得稍微容易一些,并减少了维护负担。您可以在此处阅读有关TypeScript的更多信息。