TypeScript高级类型:探索Mapped Types的威力及衍生

简介: TypeScript高级类型:探索Mapped Types的威力及衍生

TypeScript是一种强类型的编程语言,它在JavaScript的基础上添加了静态类型检查。除了基本的类型系统外,TypeScript还提供了许多高级类型特性,其中之一就是Mapped Types(映射类型)。Mapped Types是一种强大的工具,可以根据现有类型创建新的类型。

Mapped Types

Mapped Types的威力在于它们允许我们对现有类型进行转换修改,从而创建出更具表现力和灵活性的类型。通过使用Mapped Types,我们可以轻松地进行属性的重命名、添加或删除属性、将属性设置为可选或只读,甚至可以根据现有属性的类型创建新的属性。

一个常见的用例是将现有类型的所有属性设置为只读。通过使用Readonly Mapped Type,我们可以轻松地实现这一目标。例如,假设我们有一个名为Person的接口,其中包含nameage属性。我们可以使用Readonly Mapped Type将Person接口中的所有属性设置为只读

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

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = {
   
  name: "John",
  age: 30
};

person.name = "Jane"; // Error: Cannot assign to 'name' because it is a read-only property.

除了Readonly Mapped Type外,TypeScript还提供了许多其他的Mapped Types,如PartialRequiredPick等。这些Mapped Types可以根据我们的需求对现有类型进行灵活的转换和修改。

另一个强大的特性是使用Mapped Types进行属性的重命名。通过使用Record Mapped Type,我们可以将一个类型中的属性重命名为另一个类型中的属性。例如,假设我们有一个名为User的接口,其中包含usernameemail属性。我们可以使用Record Mapped Type将User接口中的username属性重命名为name

interface User {
   
  username: string;
  email: string;
}

type RenamedUser = Record<"name", User["username"]> & Omit<User, "username">;

const user: RenamedUser = {
   
  name: "John",
  email: "john@example.com"
};

console.log(user.name); // Output: "John"
console.log(user.email); // Output: "john@example.com"

总结:

本文介绍了TypeScript中的Mapped Types,探索了它们的威力和实用性。Mapped Types允许我们根据现有类型创建新的类型,并进行属性的转换和修改。通过使用Mapped Types,我们可以轻松地实现属性的重命名、添加或删除属性、将属性设置为只读或可选等操作。掌握Mapped Types将使我们的代码更具表现力和灵活性,提高代码的可维护性和可扩展性。

衍生知识点

当涉及到Mapped Types时,其实还有其他较多的类似知识点,我们可以稍微提及一下。

  1. 条件类型(Conditional Types):条件类型是TypeScript中另一个强大的类型工具,它允许我们根据条件选择不同的类型。条件类型通常与Mapped Types结合使用,以根据某些条件转换或修改类型。通过使用条件类型,我们可以实现更复杂的类型转换和操作。
  2. keyof 操作符:keyof 操作符用于获取一个类型的所有属性名,它返回一个由属性名组成的联合类型。在Mapped Types中,我们经常使用keyof操作符来遍历和操作类型的属性。
    keyof
interface Person {
   
  name: string;
  age: number;
  address: string;
}

type PersonKeys = keyof Person; // "name" | "age" | "address"

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

const person: Person = {
   
  name: "John",
  age: 30,
  address: "123 Main St"
};

console.log(getProperty(person, "name")); // Output: "John"
console.log(getProperty(person, "age")); // Output: 30
console.log(getProperty(person, "address")); // Output: "123 Main St"

在上面的示例中,我们使用keyof操作符获取了Person接口的所有属性名,并将其存储在PersonKeys类型中。然后,我们定义了一个名为getProperty的函数,它接受一个对象和一个属性名作为参数,并返回该属性的值。

  1. infer 关键字:infer 关键字用于在条件类型中推断类型变量。它允许我们从一个类型中提取出另一个类型,并将其用于条件类型的结果。infer 关键字通常与条件类型和Mapped Types一起使用,以实现类型的推断和转换。

infer关键字示例

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function sum(a: number, b: number): number {
   
  return a + b;
}

type SumReturnType = ReturnType<typeof sum>; // number

console.log(typeof sum(2, 3)); // Output: "number"

在上面的示例中,我们定义了一个名为ReturnType的类型,它接受一个函数类型T作为参数。我们使用条件类型和infer关键字来推断函数的返回类型。然后,我们定义了一个名为sum的函数,并使用SumReturnType类型来推断sum函数的返回类型。

  1. 索引类型(Index Types):索引类型允许我们通过索引访问类型的属性。在Mapped Types中,我们可以使用索引类型来动态地访问和操作类型的属性。

索引类型示例

interface Dictionary<T> {
   
  [key: string]: T;
}

const dictionary: Dictionary<number> = {
   
  a: 1,
  b: 2,
  c: 3
};

console.log(dictionary["a"]); // Output: 1
console.log(dictionary["b"]); // Output: 2
console.log(dictionary["c"]); // Output: 3

我们定义了一个名为Dictionary的接口,它使用索引类型来定义一个字符串索引和对应的值类型。然后,我们创建了一个名为dictionary的对象,它的键是字符串,值是数字类型。我们可以使用索引访问运算符来访问和操作dictionary对象的属性。

  1. 映射类型的递归和嵌套:Mapped Types可以嵌套和递归使用,以创建更复杂的类型转换和操作。通过嵌套和递归使用Mapped Types,我们可以实现更高级的类型转换和修改。
相关文章
|
29天前
|
设计模式 JavaScript 安全
TypeScript性能优化及代码质量提升的重要性、方法与策略,包括合理使用类型注解、减少类型断言、优化模块导入导出、遵循编码规范、加强代码注释等
本文深入探讨了TypeScript性能优化及代码质量提升的重要性、方法与策略,包括合理使用类型注解、减少类型断言、优化模块导入导出、遵循编码规范、加强代码注释等,旨在帮助开发者在保证代码质量的同时,实现高效的性能优化,提升用户体验和项目稳定性。
42 6
|
28天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
36 2
|
1月前
|
JavaScript 安全 前端开发
TypeScript类型声明:基础与进阶
通过本文的介绍,我们详细探讨了TypeScript的基础与进阶类型声明。从基本数据类型到复杂的泛型和高级类型,TypeScript提供了丰富的工具来确保代码的类型安全和可维护性。掌握这些类型声明能够帮助开发者编写更加健壮和高效的代码,提高开发效率和代码质量。希望本文能为您在使用TypeScript时提供实用的参考和指导。
38 2
|
1月前
|
JavaScript 开发者
在 Babel 插件中使用 TypeScript 类型
【10月更文挑战第23天】可以在 Babel 插件中更有效地使用 TypeScript 类型,提高插件的开发效率和质量,减少潜在的类型错误。同时,也有助于提升代码的可理解性和可维护性,使插件的功能更易于扩展和升级。
|
2月前
|
JavaScript 前端开发
TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第11天】TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
2月前
|
JavaScript 前端开发 安全
TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第9天】TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
1月前
|
JavaScript 前端开发 安全
TypeScript进阶:类型系统与高级类型的应用
【10月更文挑战第25天】TypeScript作为JavaScript的超集,其类型系统是其核心特性之一。本文通过代码示例介绍了TypeScript的基本数据类型、联合类型、交叉类型、泛型和条件类型等高级类型的应用。这些特性不仅提高了代码的可读性和可维护性,还帮助开发者构建更健壮的应用程序。
33 0
|
3月前
|
JavaScript
typeScript进阶(9)_type类型别名
本文介绍了TypeScript中类型别名的概念和用法。类型别名使用`type`关键字定义,可以为现有类型起一个新的名字,使代码更加清晰易懂。文章通过具体示例展示了如何定义类型别名以及如何在函数中使用类型别名。
49 1
typeScript进阶(9)_type类型别名
|
2月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
64 0
|
2月前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与实用技巧
【10月更文挑战第8天】深入理解TypeScript:类型系统与实用技巧