keyof 在 Typescript 中的工作原理

在 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成为或。我们可以定义它的一种方法是:nameemailage

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的更多信息