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

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

引言

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

基本概念

在 TypeScript 中,类型是一种值的属性。通过将值与其对应的类型进行关联,我们可以在编译时检查代码中的类型错误。而类型演算则是对这些类型进行操作和计算的过程。
TypeScript 提供了一系列内置的操作符和关键字来进行类型演算。例如,typeof 操作符可以用于获取一个值的类型;keyof关键字可以用于获取一个对象所有属性名组成的联合类型;in 关键字可以用于遍历一个联合类型中所有成员等等。

类型推断与上下文

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 类型演算时,typeofkeyofin 是三个非常重要的操作符和关键字。它们在类型系统中扮演着不同的角色,用于获取类型信息、操作对象属性和遍历联合类型成员。下面将详细讲解它们的作用及使用示例。

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。
通过使用 typeofkeyof 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>
  • Awaited<T>
  • Parameters<T>

Omit<T, K>

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

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

在上述代码中,Omit 从 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’。

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 类型。

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” 的成员。

Extract<T, U>

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

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

在上述代码中,Extract 从 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 类型演算,并在实际开发中得到应用。

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

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

相关文章

如何使用Matlab进行三角剖分(自定义函数实现delaunayTriangulation 使用Bowyer-Watson 算法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Delaunay三角形 二、使用步骤 1.Bowyer-Watson算法 2.算法步骤 三、动画演示 四、核心代码 五、对比matlab自带函数和我们的算法&#xff1a; 总结 前…

谷歌开源项目BERT源码解读与应用实例

数据及代码见文末 基于BERT的中文情感分析实战:基于BERT的中文情感分析实战-CSDN博客 基于BERT的中文命名实体识别识别实战:基于BERT的中文命名实体识别识别实战-CSDN博客 1.项目配置文件 GLUE/BERT_BASE_DIR是项目的预训练权重,预训练权重主要包含3个部分:参数配置文件…

打气球小游戏

1.气球往上飘 我们声明两个符号常量来作为窗体的长和宽,接着就是常规操作 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600#include<easyx.h> #include<stdio.h> int main() {initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);setbkcolor(WHITE);cleardevice();get…

网关过滤器使用及其原理分析

1.网关过滤器介绍 网关过滤器的用途一般是修改请求或响应信息,例如编解码、Token验证、流量复制等 官方文档地址:Spring Cloud Gateway 网关过滤器分为GloablFilter、GatewayFilter及DefaultFilter 过滤器的执行顺序由Order决定,Order值越小,优先级越高,越先执行 1.1…

vmware 安装系统提示无法启用3D加速的解决

起因&#xff1a;朋友要在虚拟机打游戏&#xff0c;然后就叫我帮忙搞虚拟机&#xff0c;安装的是当前最新的17.1.5 Pro。 说说他老母鸡的情况&#xff1a;i7 10th 32G 显卡1060&#xff0c;这个配置呢&#xff0c;开启虚拟机3D是正常没问题的。因为我的显卡也是这个。本地的显…

linux platform 总线(设备树)驱动

使用文档 设备树修改 新增一个 LED 节点 arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts my_pl_led {compatible "arm, cortex-a9-led";status "okay";};设备树编译 make dtbs日志 DTC arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtbplatform driver …

python+selenium - UI自动框架之封装浏览器引擎driver方法

在做兼容性测试的适合&#xff0c;可以运行指定的浏览器&#xff08;IE,Chrome,Edge&#xff09; 目录文件&#xff1a; from selenium import webdriver from urllib3.exceptions import ProtocolError from common.log import *def getDriver():# if browserType is None:br…

数据分析必备:一步步教你如何用Pandas做数据分析(6)

1、Pandas 函数应用 Pandas 重建索引操作实例 要将您自己或其他库的函数应用于Pandas对象&#xff0c;您应该了解三个重要的方法。方法如下所述。要使用的适当方法取决于您的函数是希望对整个数据帧进行操作&#xff0c;还是行操作还是按列操作&#xff0c;还是按元素操作。 表…

多进程操作文件

最近在调试多进程编程的时候&#xff0c;发现父进程打开过文件后&#xff0c;创建子进程&#xff0c;子进程会拷贝父进程的文件描述符&#xff0c; 举例&#xff0c;比如是串口设备&#xff0c;父进程打开串口后又关闭了串口&#xff0c;可是下次再打开就打不开了&#xff0c; …

模拟面试题

1.装箱和拆箱是指什么&#xff1f; 装箱——把栈中内容迁移到堆中去&#xff08;值转引用&#xff09; 拆箱——把堆中内容迁移到栈中去&#xff08;引用转值&#xff09; 2.值和引用类型在变量赋值时的区别是什么&#xff1f; 值类型&#xff1a;赋值时复制数据本身&a…

Gitee在已有项目基础上创建仓库中遇到的问题和解决

问题一&#xff1a;fatal: remote origin already exists 解释&#xff1a;当前仓库添加了一个名为"origin"的远程仓库配置&#xff0c;此时输入 git remote add origin https://xxx就会提示上面的内容。 解决方案1:移除旧的origin git remote remove origin 解决方案…

C++——mapset红黑树

目录 一补充知识 1关联式容器 2键值对 二set 1set的介绍 2set的使用 三map 1map的说明 2map的使用 四容器在oj中的使用 五AVL树 1概念 2插入 3AVL的旋转 3.1右单旋 3.2左单旋 3.3左右双旋 3.4右左双旋 4判断AVL树是否平衡 完整源代码 六红黑树 1概念 2性…

【Shader】Unity曲面弯曲效果

本期分享一个弯曲效果的Shader&#xff0c;类似于地铁跑酷的跑道 1、Shaer代码 Shader "Unlit/CurvedUnlit" { Properties{_MainTex ("Texture", 2D) "white" {}}SubShader{Tags { "RenderType""Opaque" }LOD 100Pass{CGP…

紫光展锐突破创新终端品类,搭载展锐芯的全球首款二合一5G云电脑正式发布

近日&#xff0c;搭载紫光展锐5G芯片T760的中兴云电脑逍遥系列正式发布&#xff0c;亮点&#xff1a; 全球首款二合一5G云电脑&#xff0c;支持本地/云端双模式&#xff0c;一键切换&#xff0c;用户可同时享有Android平板和Windows云电脑两种形态&#xff1b;支持5G蜂窝网络&…

C++相关概念和易错语法(13)(string的模拟实现)

string由于存在字符串和单字符的概念&#xff0c;使得它的一些接口&#xff0c;实现要比vector多一些。本质上来看string的实现是在顺序表的基础上加入串相关的操作。下面我会分享如何模拟实现string&#xff0c;这可以进一步提高我们对string的熟练程度。 1.构造函数、拷贝构…

附代码:策略常用-正余弦优化算法

正余弦优化算法作为群智能优化算法的一种, 正弦余弦算法 (sine cosine algorithm, SCA) 是 2016 年由 Mirjalili 提出的一种新型仿自然优化算法, 通过创建多个随机候选解, 利用正余弦函数的数学性质来平衡算法在搜系过程中的全局探索和局部开发能力。该算法具有结构简单、参数少…

docker三种自定义网络(虚拟网络) overlay实现原理

docker提供了三种自定义网络驱动&#xff1a;bridge、overlay、macvlan。 bridge驱动类似默认的bridge网络模式。 overlay和macvlan是用于创建跨主机网络。 支持自定义网段、网关&#xff0c;docker network create --subnet 172.77.0.0/24 --gateway 172.77.0.1 my_n…

PPT大珩助手新功能-生成迷宫

大珩助手是一款功能丰富的办公软件插件&#xff0c;它主要分为两个版本&#xff1a;PPT大珩助手和Word大珩助手。这两个版本都旨在提高用户在处理演示文稿和文档时的效率。 PPT大珩助手 这是一款专门为Microsoft PowerPoint设计的插件。它提供了多种功能&#xff0c;例如素材…

类与对象:抽象类、Object类和内部类

一.抽象类 1.概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类。 抽象类也是类&#…

盲人社区生活支持体系:织就一张温暖的网

在当今社会&#xff0c;构建一个全面、包容的盲人社区生活支持体系成为了推动社会进步、保障残障人士权益的重要议题。随着科技的不断革新&#xff0c;一款名为“蝙蝠避障”的辅助软件走进了盲人的日常生活&#xff0c;它如同一位无形的向导&#xff0c;通过实时避障与拍照识别…