TypeScript - Оператор keyof

Здравствуйте,野心勃勃的程序员们!今天,我们将踏上一段激动人心的旅程,探索TypeScript的世界,并了解其强大的特性之一:keyof 类型操作符。如果你是编程新手,不用担心;我会一步一步地引导你理解这个概念,就像我在多年的教学过程中帮助无数学生那样。所以,拿起一杯咖啡(或者你最喜欢的饮料),让我们开始吧!

TypeScript - Keyof Type Operator

什么是 keyof 类型操作符?

在我们深入了解之前,让我们先了解一下 keyof 类型操作符是什么。想象你有一个宝箱(在编程术语中指的是一个对象),你想知道所有可能的钥匙来打开它。这正是 keyof 所做的 —— 它为你提供了一个对象类型中所有“键”(属性名)的列表。

一个简单的类比

想象一下一本书的索引。keyof 操作符就像是在问:“这本书涵盖了哪些主题?”它为你提供了索引中所有的条目。

语法

使用 keyof 类型操作符的语法很简单:

type Keys = keyof ObjectType;

在这里,ObjectType 是你感兴趣的对象类型,而 Keys 将是 ObjectType 中所有属性名的联合类型。

示例

让我们看一些示例,真正理解 keyof 是如何工作的。我们将从简单的例子开始,然后逐渐增加复杂度。

示例 1:基本使用

interface Person {
name: string;
age: number;
city: string;
}

type PersonKeys = keyof Person;

// PersonKeys 等同于: "name" | "age" | "city"

在这个例子中,我们有一个带有三个属性的 Person 接口。当我们使用 keyof Person 时,TypeScript 给我们提供了 Person 中所有属性名的联合类型。

示例 2:在变量中使用 keyof

const person: Person = {
name: "Alice",
age: 30,
city: "Wonderland"
};

function getProperty(obj: Person, key: keyof Person) {
return obj[key];
}

console.log(getProperty(person, "name")); // 输出:Alice
console.log(getProperty(person, "age"));  // 输出:30
// console.log(getProperty(person, "job")); // 错误:参数类型 '"job"' 无法赋值给参数类型 'keyof Person'。

在这里,我们创建了一个 getProperty 函数,它接受一个 Person 对象和一个 Person 的键。TypeScript 确保我们只能使用 Person 的有效键,从而在编译时防止错误。

示例 3:动态属性访问

function pluck<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
return keys.map(key => obj[key]);
}

const car = {
make: "Toyota",
model: "Corolla",
year: 2020
};

const result = pluck(car, ["make", "year"]);
console.log(result); // 输出:["Toyota", 2020]

在这个更高级的例子中,我们创建了一个 pluck 函数,它可以与任何对象类型一起工作。它接受一个对象和一个键的数组,返回一个相应值的数组。

示例 4:将 keyof 与映射类型结合使用

type Optional<T> = {
[K in keyof T]?: T[K];
};

interface User {
id: number;
name: string;
email: string;
}

type OptionalUser = Optional<User>;

// OptionalUser 等同于:
// {
//   id?: number;
//   name?: string;
//   email?: string;
// }

const partialUser: OptionalUser = { name: "Bob" }; // 这是有效的

在这里,我们创建了一个实用类型 Optional,它使得一个类型的所有属性变为可选。我们使用 keyof 结合映射类型来实现这一点。

方法表格

下面是总结我们所涵盖的关键方法和概念的表格:

方法/概念 描述 示例
keyof 返回一个对象类型的所有属性名的联合类型 type Keys = keyof Person
属性访问 使用 keyof 访问对象属性 obj[key as keyof ObjectType]
泛型约束 使用 keyof 约束泛型类型 K extends keyof T
映射类型 结合 keyof 和映射类型进行类型转换 [K in keyof T]?: T[K]

结论

就这样,朋友们!我们已经穿越了 TypeScript 中的 keyof 之地。从基本用法到更高级的场景,你已经看到了这个强大的操作符如何使你的代码更加类型安全且灵活。

记住,就像学习任何新技能一样,掌握 TypeScript 及其特性需要练习。如果一开始不能立即掌握,不要气馁。继续尝试,尝试不同的示例,很快你就能像专业人士一样使用 keyof

就像我总是告诉我的学生那样,编程就像烹饪一样 —— 你理解的“配料”(概念)越多,你的“食谱”(程序)就会变得越美味(高效且健壮)。所以,继续搅拌你的 TypeScript 大锅,祝编码愉快!

Credits: Image by storyset