TypeScript进阶(三)类型演算与高级内置类型

news2025/1/8 4:49:22

✨ 专栏介绍

TypeScript是一种由微软开发的开源编程语言,它是JavaScript的超集,意味着任何有效的JavaScript代码都是有效的TypeScript代码。TypeScript通过添加静态类型和其他特性来增强JavaScript,使其更适合大型项目和团队开发。

在TypeScript专栏中,我们将深入探讨TypeScript的各个方面,包括语法、类型系统、模块化、面向对象编程等。我们将介绍如何使用TypeScript来构建可维护、可扩展和高效的应用程序。

TypeScript是一种开源的编程语言,它是JavaScript的超集,意味着所有的JavaScript代码都可以在TypeScript中运行。TypeScript添加了静态类型检查和其他一些新特性,以提高代码的可读性、可维护性和可扩展性。
在这里插入图片描述

文章目录

    • ✨ 专栏介绍
    • 引言
    • 基本概念
    • 类型推断与上下文
    • 类型操作符
    • 条件类型
    • 映射类型
    • 类型守卫
    • 类型演算的应用
    • 操作符
      • typeof 操作符
      • keyof 关键字
      • in 关键字
    • 内置类型
        • `Omit<T, K>`
        • `Pick<T, K>`
        • `Record<K, T>`
        • `Partial<T>`
        • `Required<T>`
        • `Readonly<T>`
        • `Exclude<T, U>`
        • `Extract<T, U>`
        • `NonNullable<T>`
        • `ReturnType<T>`
        • `InstanceType<T>`
        • `Awaited<T>`
        • `Parameters<T>`
    • 总结
    • 😶 写在结尾


引言

TypeScript 是一种静态类型检查的 JavaScript 超集,它通过类型注解和类型推断来提供更强大的类型系统。在 TypeScript 中,类型演算是一种重要的概念,它允许我们在编译时对类型进行操作和计算。本文将深入探讨 TypeScript 类型演算的原理和应用。

基本概念

在 TypeScript 中,类型是一种值的属性。通过将值与其对应的类型进行关联,我们可以在编译时检查代码中的类型错误。而类型演算则是对这些类型进行操作和计算的过程。

TypeScript 提供了一系列内置的操作符和关键字来进行类型演算。例如,typeof 操作符可以用于获取一个值的类型;keyof 关键字可以用于获取一个对象所有属性名组成的联合类型;in 关键字可以用于遍历一个联合类型中所有成员等等。

类型推断与上下文

在 TypeScript 中,编译器会根据上下文自动推断变量或表达式的类型。这种基于上下文的推断机制使得代码更加简洁且易读。

例如,在以下代码中:

let x = 10;

编译器会自动推断变量 x 的类型为 number。这是因为赋给 x 的值是一个数字字面量。

类型操作符

TypeScript 提供了一系列类型操作符,用于对类型进行操作和计算。这些操作符包括联合类型(|)、交叉类型(&)、索引访问操作符([])、条件类型(extends ? :)等等。

例如,我们可以使用联合类型来定义一个变量可以接受多种不同类型的值:

let x: number | string;

这样,变量 x 可以接受 number 类型或 string 类型的值。

条件类型

条件类型是 TypeScript 中一种非常强大的类型演算工具。它允许我们根据某个条件来选择不同的类型。

例如,我们可以使用条件类型来实现一个根据输入参数的不同返回不同结果的函数:

type Result<T> = T extends number ? string : boolean;

function getResult<T>(input: T): Result<T> {
  if (typeof input === "number") {
    return "number";
  } else {
    return true;
  }
}

在上述代码中,如果输入参数是一个数字,则返回字符串类型;否则返回布尔值。

映射类型

映射类型是 TypeScript 中一种非常有用的工具,它允许我们根据已有的对象定义新的对象类型。

例如,我们可以使用映射类型来将一个对象中所有属性都设置为只读:

type ReadonlyObject<T> = {
  readonly [P in keyof T]: T[P];
};

const obj: ReadonlyObject<{ name: string; age: number }> = {
  name: "Alice",
  age: 20,
};

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

类型守卫

类型守卫是 TypeScript 中一种用于缩小类型范围的机制。通过使用类型守卫,我们可以在特定条件下判断一个值的类型,并在代码块中使用该类型。

例如,我们可以使用 typeof 操作符来判断一个值的类型,并在代码块中使用该类型:

function printValue(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase());
  } else {
    console.log(value.toFixed(2));
  }
}

在上述代码中,如果 value 是一个字符串,则将其转换为大写字母并打印;否则将其保留两位小数并打印。

类型演算的应用

通过深入理解 TypeScript 类型演算,我们可以更好地利用 TypeScript 的强大类型系统来编写更安全、更健壮的代码。

例如,在开发过程中,我们经常需要对输入参数进行验证和处理。通过使用条件类型和映射类型等工具,我们可以根据输入参数的不同来选择不同的处理逻辑,并根据已有对象定义新的对象类型。

此外,在编写通用库或框架时,类型演算也是非常有用的。通过使用类型演算,我们可以实现更加灵活和可扩展的类型定义,从而提供更好的类型推断和代码提示。

操作符

当谈到 TypeScript 类型演算时,typeof、keyof 和 in 是三个非常重要的操作符和关键字。它们在类型系统中扮演着不同的角色,用于获取类型信息、操作对象属性和遍历联合类型成员。下面将详细讲解它们的作用及使用示例。

typeof 操作符

typeof 是一个在 JavaScript 中已经存在的操作符,用于获取一个值的类型。在 TypeScript 中,typeof 操作符也可以用于获取一个值的类型,并将其作为一个类型注解或类型声明使用。

let x = 10;
let y: typeof x; // y 的类型为 number

在上述代码中,typeof x 返回 number 类型,并将其赋值给变量 y。

keyof 关键字

keyof 是 TypeScript 中的一个关键字,用于获取一个对象所有属性名组成的联合类型。通过 keyof 关键字,我们可以在编译时获取对象属性名,并将其作为一个类型注解或类型声明使用。

type Person = {
 name: string;
 age: number;
};

type PersonKeys = keyof Person; // PersonKeys 的类型为 "name" | "age"

在上述代码中,keyof Person 返回 “name” | “age” 类型,并将其赋值给 PersonKeys。

in 关键字

in 是 TypeScript 中的一个关键字,用于遍历一个联合类型中所有成员。通过 in 关键字,我们可以在编译时对联合类型进行遍历,并将其作为一个类型注解或类型声明使用。

type Fruit = "apple" | "banana" | "orange";

type FruitInfo = {
 [P in Fruit]: number;
};

const fruitCount: FruitInfo = {
 apple: 5,
 banana: 3,
 orange: 2,
};

在上述代码中,[P in Fruit] 表示遍历 Fruit 联合类型中的所有成员,并将其作为 FruitInfo 对象的属性名,属性值的类型为 number。

通过使用 typeof、keyof 和 in,我们可以在 TypeScript 中对类型进行操作和计算,从而实现更加灵活和可扩展的类型定义。这些操作符和关键字在实际开发中非常有用,可以帮助我们编写更安全、更健壮的代码,并提高开发效率。

内置类型

  • Omit<T, K>
  • Pick<T, K>
  • Record<K, T>
  • Partial<T>
  • Required<T>
  • Readonly<T>
  • Exclude<T, U>
  • Extract<T, U>
  • NonNullable<T>
  • ReturnType<T>
  • InstanceType<T>
Omit<T, K>

Omit<T, K> 用于从类型 T 中排除指定属性 K。它会创建一个新的类型,其中排除了属性 K。

type Person = {
 name: string;
 age: number;
 address: string;
};
type PersonWithoutAddress = Omit<Person, 'address'>;
// PersonWithoutAddress 的类型为 { name: string; age: number; }

在上述代码中,Omit<Person, ‘address’> 从 Person 类型中排除了属性 ‘address’。

Pick<T, K>

用于从类型 T 中选择指定属性 K。它会创建一个新的类型,其中只包含属性 K。

type Person = {
 name: string;
 age: number;
 address: string;
};
type PersonNameAndAge = Pick<Person, 'name' | 'age'>;
// PersonNameAndAge 的类型为 { name: string; age: number; }

在上述代码中,Pick<Person, ‘name’ | ‘age’> 从 Person 类型中选择了属性 ‘name’ 和 ‘age’。

Record<K, T>

用于创建一个新的对象类型,其中键为类型 K 中的值,值为类型 T。

type Fruit = 'apple' | 'banana' | 'orange';
type FruitCount = Record<Fruit, number>;
// FruitCount 的类型为 { apple: number; banana: number; orange: number; }

在上述代码中,Record<Fruit, number> 创建了一个对象类型,其中键为 Fruit 类型中的值,值为 number 类型。

Partial<T>

用于将类型 T 中的所有属性变为可选属性。它会创建一个新的类型,其中所有属性都变为可选。

type Person = {
  name: string;
  age: number;
};

type PartialPerson = Partial<Person>;
// PartialPerson 的类型为 { name?: string; age?: number; }

在上述代码中,Partial<Person> 将 Person 类型中的所有属性变为可选属性。

Required<T>

用于将类型 T 中的所有属性变为必选属性。它会创建一个新的类型,其中所有属性都变为必选。

type PartialPerson = {
  name?: string;
  age?: number;
};

type RequiredPerson = Required<PartialPerson>;
// RequiredPerson 的类型为 { name: string; age: number; }

在上述代码中,Required<PartialPerson> 将 PartialPerson 类型中的所有属性变为必选属性。

Readonly<T>

用于将类型 T 中的所有属性变为只读属性。它会创建一个新的类型,其中所有属性都变为只读。

type Person = {
  name: string;
  age: number;
};

type ReadonlyPerson = Readonly<Person>;
// ReadonlyPerson 的类型为 { readonly name: string; readonly age: number; }

在上述代码中,Readonly<Person> 将 Person 类型中的所有属性变为只读属性。

Exclude<T, U>

用于从类型 T 中排除类型 U。它会创建一个新的类型,其中排除了类型 U 的成员。

type Fruit = "apple" | "banana" | "orange";
type ExcludeFruit = Exclude<Fruit, "banana">;
// ExcludeFruit 的类型为 "apple" | "orange"

在上述代码中,Exclude<Fruit, “banana”> 从 Fruit 类型中排除了值为 “banana” 的成员。

Extract<T, U>

用于从类型 T 中提取出类型 U。它会创建一个新的类型,其中只包含类型 U 的成员。

type Fruit = "apple" | "banana" | "orange";
type ExtractFruit = Extract<Fruit, "banana">;
// ExtractFruit 的类型为 "banana"

在上述代码中,Extract<Fruit, “banana”> 从 Fruit 类型中提取出值为 “banana” 的成员。

NonNullable<T>

用于从类型 T 中排除 null 和 undefined。它会创建一个新的类型,其中不包含 null 和 undefined。

type Value = string | null | undefined;
type NonNullableValue = NonNullable<Value>;
// NonNullableValue 的类型为 string

在上述代码中,NonNullable<Value> 从 Value 类型中排除了 null 和 undefined。

ReturnType<T>

用于获取函数类型 T 的返回值类型。它会创建一个新的类型,其中只包含函数 T 的返回值类型。

type MyFunction = () => string;
type MyFunctionReturnType = ReturnType<MyFunction>;
// MyFunctionReturnType 的类型为 string

在上述代码中,ReturnType<MyFunction> 获取了函数类型 MyFunction 的返回值类型。

InstanceType<T>

用于获取构造函数类型 T 的实例类型。它会创建一个新的类型,其中只包含构造函数 T 的实例类型。

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

type PersonInstance = InstanceType<typeof Person>;
// PersonInstance 的类型为 Person

在上述代码中,InstanceType<typeof Person> 获取了构造函数 Person 的实例类型。

Awaited<T>

用于获取 Promise 类型 T 的解析值类型。它会创建一个新的类型,其中包含了 Promise 类型 T 的解析值类型。

async function fetchData(): Promise<string> {
  return "Data";
}

type AwaitedData = Awaited<ReturnType<typeof fetchData>>;
// AwaitedData 的类型为 string

在上述代码中,Awaited<ReturnType<typeof fetchData>> 获取了 fetchData 函数返回 Promise 的解析值类型。

Parameters<T>

用于获取函数类型 T 的参数类型组成的元组。它会创建一个新的类型,其中包含了函数 T 的参数类型组成的元组。

function greet(name: string, age: number): void {
  console.log(`Hello, ${name}! You are ${age} years old.`);
}

type GreetParams = Parameters<typeof greet>;
// GreetParams 的类型为 [string, number]

在上述代码中,Parameters<typeof greet> 获取了 greet 函数的参数类型组成的元组。

通过这些 TypeScript 类型操作符,我们可以更灵活地操作和计算类型,并提供更强大的静态类型检查。这些操作符在实际开发中非常有用,可以帮助我们编写更安全、更健壮的代码,并提高开发效率。

总结

本文深入探讨了 TypeScript 类型演算的原理和应用。通过使用类型演算,我们可以在编译时对类型进行操作和计算,从而提供更强大的类型系统。通过合理地运用类型推断、条件类型、映射类型等工具,我们可以编写更安全、更健壮的代码,并提高开发效率。希望本文能够帮助读者深入理解 TypeScript 类型演算,并在实际开发中得到应用。


😶 写在结尾

前端设计模式专栏
在这里插入图片描述
设计模式是软件开发中不可或缺的一部分,它们帮助我们解决了许多常见问题,并提供了一种优雅而可靠的方式来构建应用程序。在本专栏中,我们介绍了所有的前端设计模式,包括观察者模式、单例模式、策略模式等等。通过学习这些设计模式,并将其应用于实际项目中,我们可以提高代码的可维护性、可扩展性和可重用性。希望这个专栏能够帮助你在前端开发中更好地应用设计模式,写出高质量的代码。点击订阅前端设计模式专栏

Vue专栏
在这里插入图片描述
Vue.js是一款流行的JavaScript框架,用于构建用户界面。它采用了MVVM(Model-View-ViewModel)的架构模式,通过数据驱动和组件化的方式,使开发者能够更轻松地构建交互性强、可复用的Web应用程序。在这个专栏中,我们将深入探讨Vue.js的核心概念、组件开发、状态管理、路由和性能优化等方面的知识。我们将学习如何使用Vue.js构建响应式的用户界面,并探索其强大的生态系统,如Vue Router和Vuex、Pinia。通过学习这些内容,你将能够成为一名熟练的Vue.js开发者,并能够应用这些知识来构建复杂而高效的Web应用程序。点击订阅Vue专栏

JavaScript(ES6)专栏在这里插入图片描述
JavaScript是一种广泛应用于网页开发和后端开发的脚本语言。它具有动态性、灵活性和易学性的特点,是构建现代Web应用程序的重要工具之一。在这个专栏中,我们将深入探讨JavaScript语言的基本语法、DOM操作、事件处理、异步编程以及常见算法和数据结构等内容。此外,我们还将介绍ES6(ECMAScript 2015)及其后续版本中引入的新特性,如箭头函数、模块化、解构赋值等。通过学习这些内容,你将能够成为一名熟练的JavaScript开发者,并能够应用这些知识来构建出高质量和可维护的Web应用程序。点击订阅JavaScript(ES6)专栏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1373790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python爬虫实战(8)--获取虎pu热榜

1. 需要的类库 import requests from bs4 import BeautifulSoup import pandas as pd2. 请求地址 def fetch_data():url "https://bbs.xxx.com/" # Replace with the actual base URLresponse requests.get(url)if response.status_code 200:return response.c…

外汇天眼:Options与OneTick合作,共同打造全球SAAS分析平台

Options Technology&#xff0c;一家为全球金融领域提供云服务的托管服务提供商&#xff0c;今天宣布与OneMarketData及其旗舰产品OneTick平台的合作。 Options将使OneTick订户能够访问其庞大的市场数据存储库&#xff0c;包括股票、外汇、期货、期权和固定收益数据&#xff0…

掌握Sketch:软件介绍与实用技巧分享

Sketch是最好的UI软件之一。它可以快速交互迭代&#xff0c;每个页面之间的小部件可以直接复制粘贴并修改。在整体架构布局中&#xff0c;可以直接下载很多Mocaup模板&#xff0c;所以非常快。这个工具完全是为应用程序设计的&#xff0c;比PS好得多。 如果你不知道sketch软件…

Android Firebase (FCM)推送接入

官方文档&#xff1a; 向后台应用发送测试消息 | Firebase Cloud Messaging 1、根级&#xff08;项目级&#xff09;Gradlegradle的dependencies中添加&#xff1a; dependencies {...// Add the dependency for the Google services Gradle pluginclasspath com.google.gm…

open3d相关操作总结

open3d其实有很多交互式命令&#xff0c;在运行程序打开了open3d渲染的窗口后&#xff0c;鼠标点击窗口&#xff0c;按H就会弹出&#xff0c;交互命令的帮助&#xff0c;如下图所示&#xff1a; 其中比较常用的有&#xff1a; Q &#xff1a;退出当前窗口 H&#xff1a;打印帮…

CAN与CAN FD通信之间存在的问题

关注菲益科公众号—>对话窗口发送 “CANoe ”或“INCA”&#xff0c;即可获得canoe入门到精通电子书和INCA软件安装包&#xff08;不带授权码&#xff09;下载地址。 目录 1、通讯速率和数据长度不同的问题 2、非ISO CAN FD与ISO CAN FD设备的通讯问题 3、多设备切换的通…

PHP企业物资管理系统源码带文字安装教程

PHP企业物资管理系统源码带文字安装教程 技术架构 主要框架 : PHP7.0 laravel5.4  mysql5.5.36 composer1.3.2(依赖管理) 前端 : jquery bootstrap jstree&#xff08;树形结构&#xff09; echart&#xff08;图表&#xff09; layer&#xff08;弹出层&#xff09; 企…

参数小,性能强!开源多模态模型—TinyGPT-V

安徽工程大学、南洋理工大学和理海大学的研究人员开源了多模态大模型——TinyGPT-V。 TinyGPT-V以微软开源的Phi-2作为基础大语言模型&#xff0c;同时使用了视觉模型EVA实现多模态能力。尽管TinyGPT-V只有28亿参数&#xff0c;但其性能可以媲美上百亿参数的模型。 此外&…

TDengine 签约西电电力

近年来&#xff0c;随着云计算和物联网技术的迅猛发展&#xff0c;传统电力行业正朝着数字化、信息化和智能化的大趋势迈进。在传统业务基础上&#xff0c;电力行业构建了信息网络、通信网络和能源网络&#xff0c;致力于实现发电、输电、变电、配电和用电的实时智能联动。在这…

企业办公终端文件数据\资料防泄密软件系统 | 自动智能透明加密保护核心文件,防止外泄

文档加密/数据安全 天锐绿盾是一款终端文件数据防泄密软件系统&#xff0c;采用自动智能透明加密技术&#xff0c;可以保护核心文件不被外泄。该软件通过对终端文件的加密处理&#xff0c;使得文件只能在经过授权的计算机上正常显示和使用&#xff0c;一旦离开授权范围&#x…

three.js : tweenjs创建threejs动画

效果&#xff1a; 代码 <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div> <div class"box-right"><…

在本地服务器发送邮件不可以,生产环境下跑可以

公司一般会给一个smtp-xxxx.com mail:host: smtp-xxxx.comport: 25properties:mail:smtp:starttls:enable: falsedebug: true然后你会使用堡垒机映射ip 会发现在本地邮件根本不会发出去,只能拿到虚拟机上跑 解决方案 我们需要把smtp-xxxx.com,改成对应的ip地址,只需要把smtp…

JavaScript中7种常见删除数组中指定元素的方法(含代码)

在JavaScript中&#xff0c;有多种方法可以从数组中删除指定的元素。以下是几种常见的方法&#xff1a; 1. 使用 splice() 方法 splice() 方法可以同时从数组中删除和添加元素。如果只提供了两个参数&#xff0c;那么它只会删除元素。 let arr [1, 2, 3, 4, 5]; let ind…

直播预告丨看零售场,如何玩转 MaaS

今年&#xff0c;有一个被频繁提及的词是MaaS 这类工具正在帮助千行百业实现大模型落地产业 在零售场&#xff0c;特别是像京东这样拥有超高并发、超复杂协同的电商场内 也沉淀出了一套通用的AI基础设施——九数算法中台 从提升客户服务体验、平台效率出发&#xff0c;训练各…

JS逆向实战案例2——某房地产token RSA加密

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、 反爬分析 url1&#xff1a;aHR0cDovL3pmY2ouZ3ouZ292LmNuL3pmY2ovZnl4eC94a2I/c1Byb2plY3RJZD05MzBlMDQ0MmJjNjA0MTBkYTgzNzQ0MmQ…

频率阈图像滤波

介绍 频率阈图像滤波是一种在频域中进行图像处理的方法&#xff0c;它基于图像的频率分布来实现滤波效果。具体步骤如下&#xff1a; 将原始图像转换到频域&#xff1a;使用快速傅里叶变换&#xff08;FFT&#xff09;将图像从空间域转换到频域。对频域图像应用频率阈滤波器&a…

Tensorflow Lite从入门到精通

TensorFlow Lite 是 TensorFlow 在移动和 IoT 等边缘设备端的解决方案&#xff0c;提供了 Java、Python 和 C API 库&#xff0c;可以运行在 Android、iOS 和 Raspberry Pi 等设备上。目前 TFLite 只提供了推理功能&#xff0c;在服务器端进行训练后&#xff0c;经过如下简单处…

斯坦福Mobile ALOHA提到的ACT之外的另两项技术:Diffusion Policy、VINN

前言 本文接上一篇文章《斯坦福机器人Mobile ALOHA的关键技术&#xff1a;动作分块ACT的算法原理与代码剖析》而来&#xff0c;当然最开始本文是作为上一篇文章的第二、第三部分的 但因为ACT太过关键&#xff0c;除了在上一篇文章中写清楚其算法原理之外&#xff0c;还得再剖…

Java研学-三层架构实现简单登录操作

一 登录流程 将服务器资源给有权限的人访问&#xff0c;只有登录的管理员可以访问员工信息进行 CRUD 二 三层架构 Web 开发中的最佳实践&#xff1a;分层开发模式将整个业务应用划分为&#xff1a;表现层、业务逻辑层、数据访问层。区分层次的目的即为了“高内聚低耦合”的思想…

2023启示录 | 商业航天这一年

图片&#xff5c;SpaceX ©⾃象限原创 作者丨罗辑 编辑丨程心 整个2023年&#xff0c;在全球热度上能够和ChatGPT一争高下的&#xff0c;可能只有SpaceX的两次星舰发射。 就像2023年菜市场卖鱼的大爷都能聊两句大模型一样&#xff0c;即使从来不关心航天的人也会知道星舰…