当前位置: 首页 > news >正文

TypeScript使用技巧

文章目录

    • 使用技巧
    • TypeScript内置的工具类型
    • keyof
    • extends 限定泛型
    • interface 与 type 区别

TypeScript作为JavaScript的超集,通过提供静态类型系统和对ES6+新特性的支持,使JavaScript开发变得更加高效和可维护。掌握TypeScript的使用技巧,可以帮助我们更好地开发和组织JavaScript项目。刚开始用的时候感觉好多限制,特别是配置静态类型检测后就容易各种报错,恨不得都用any, 那岂不是成了AnyScript,不过熟能生巧,用得多了就会爱上这个语言。这里总结了一些平时用到ts技巧。

使用技巧

当使用TypeScript进行开发时,有一些常用的技巧可以帮助你提高代码质量和开发效率。以下是一些TypeScript使用技巧:

  1. 类型注解和类型推断:尽量为变量、函数参数、函数返回值等添加类型注解,以增加代码的可读性和类型安全性。同时,TypeScript也会自动推断很多类型,充分利用类型推断特性。

  2. 使用接口和类型别名:使用接口和类型别名来定义自定义类型,使代码更具表达力和清晰度。

// 使用接口
interface Person {name: string;age: number;
}// 使用类型别名
type Point = { x: number; y: number };
  1. 泛型:使用泛型来增加代码的灵活性,使函数和类能够处理多种类型的数据。
function toArray<T>(value: T): T[] {return [value];
}
  1. 枚举:使用枚举来定义一组具有名字的常量值,提高代码可读性。
enum Color {Red,Green,Blue,
}
  1. 非空断言和可选链:使用非空断言(!)来告诉编译器一个值一定不为null或undefined,使用可选链(?.)来简化处理可能为null或undefined的属性和方法。
const name: string = maybeName!; // 非空断言
const age = person?.age; // 可选链
  1. 确定赋值断言:在声明变量时使用确定赋值断言(!)来告诉编译器该变量一定会在使用前被赋值。
let value!: number;

TypeScript内置的工具类型

当使用 TypeScript 进行开发时,有一些常用的类型工具(utility types)可以帮助你更好地处理类型,并提高代码质量和开发效率。下面是对 PartialRecordPickOmitExcludeParameters 这些类型工具的中文详细解释:

  1. Partial<Type>(部分类型):

    • Partial 是 TypeScript 内置的一个类型工具,用于使给定类型的所有属性变为可选属性。
    • 它创建了一个新的类型,其中给定类型 Type 的所有属性都变成了可选属性。
    • 示例:
    interface Person {name: string;age: number;
    }type PartialPerson = Partial<Person>;// 等同于:
    // interface PartialPerson {
    //   name?: string;
    //   age?: number;
    // }
    
  2. Record<Key, Type>(记录类型):

    • Record 是 TypeScript 内置的类型工具,用于创建一个由指定键和给定值类型组成的对象类型。
    • 它接受两个类型参数 KeyType,并创建一个对象类型,其中每个属性的键是类型 Key,值是类型 Type
    • 示例:
    type AgeMap = Record<string, number>;// 等同于:
    // interface AgeMap {
    //   [key: string]: number;
    // }
    
  3. Pick<Type, Keys>(挑选类型):

    • Pick 是 TypeScript 内置的类型工具,用于从给定类型中挑选出特定的属性形成新的类型。
    • 它接受两个类型参数 TypeKeys,并创建一个新的类型,其中只包含类型 Type 中由 Keys 指定的属性。
    • 示例:
    interface Person {name: string;age: number;address: string;
    }type PersonNameAndAge = Pick<Person, "name" | "age">;// 等同于:
    // interface PersonNameAndAge {
    //   name: string;
    //   age: number;
    // }
    
  4. Omit<Type, Keys>(省略类型):

    • Omit 是 TypeScript 内置的类型工具,用于从给定类型中省略特定的属性形成新的类型。
    • 它接受两个类型参数 TypeKeys,并创建一个新的类型,其中包含了类型 Type 中除了 Keys 指定的属性以外的所有属性。
    • 示例:
    interface Person {name: string;age: number;address: string;
    }type PersonWithoutAddress = Omit<Person, "address">;// 等同于:
    // interface PersonWithoutAddress {
    //   name: string;
    //   age: number;
    // }
    
  5. Exclude<Type, ExcludedUnion>(排除类型):

    • Exclude 是 TypeScript 内置的类型工具,用于从给定类型中排除可以赋值给 ExcludedUnion 的成员。
    • 它接受两个类型参数 TypeExcludedUnion,并创建一个新的类型,其中只包含类型 Type 中不可赋值给 ExcludedUnion 的成员。
    • 示例:
    type MyNumbers = number | string | boolean;type OnlyNumbers = Exclude<MyNumbers, string | boolean>;// 等同于:
    // type OnlyNumbers = number;
    
  6. Parameters<Type>(函数参数类型):

    • Parameters 是 TypeScript 内置的类型工具,用于从给定函数类型中提取出参数的类型。
    • 它接受一个函数类型 Type 作为参数,并返回一个由该函数的参数类型组成的元组类型。
    • 示例:
    type MyFunction = (name: string, age: number) => void;type FunctionParameters = Parameters<MyFunction>;// 等同于:
    // type FunctionParameters = [string, number];
    

keyof

在 TypeScript 中,keyof 是一个关键字和类型操作符,它用于获取一个类型的所有属性名组成的联合类型。keyof 可以结合泛型、索引类型等特性来实现许多有用的类型操作。

使用 keyof 的语法是 keyof Type,其中 Type 是一个类型。它返回一个联合类型,包含了 Type 类型中所有属性的名称。这个联合类型可以用来访问或操作 Type 类型中的属性。keyof 与 Object.keys 略有相似,只不过 keyof 取 interface 的键。

下面是一个简单的示例代码:

interface Person {name: string;age: number;gender: string;
}type PersonKey = keyof Person;
// 等同于:type PersonKey = "name" | "age" | "gender"

在这个例子中,keyof Person 返回一个联合类型,包含了 Person 类型中所有属性的名称。结果类型是 "name" | "age" | "gender"

keyof 可以与其他 TypeScript 特性结合使用,例如:

  1. 通过索引类型访问对象属性:
function getProperty<T, K extends keyof T>(obj: T, key: K) {return obj[key];
}const person: Person = { name: "Alice", age: 30, gender: "female" };
const name = getProperty(person, "name"); // name的类型是string
  1. 确定属性是否存在:
function hasProperty<T, K extends keyof T>(obj: T, key: K): boolean {return key in obj;
}const hasAge = hasProperty(person, "age"); // hasAge的值是true
const hasEmail = hasProperty(person, "email"); // hasEmail的值是false

extends 限定泛型

在 TypeScript 中,可以使用 extends 关键字来限定泛型类型的范围,确保传入的泛型参数满足一定的条件。这种方式称为"泛型约束"或"泛型限定"。通过泛型约束,我们可以对泛型进行更精确的类型检查,提高代码的类型安全性。

下面是几个使用 extends 关键字限定泛型的例子:

  1. 简单的泛型约束:
function printProperty<T extends { name: string }>(obj: T) {console.log(obj.name);
}printProperty({ name: "Alice", age: 30 }); // OK
printProperty({ age: 30 }); // Error: 缺少name属性

在这个例子中,使用 extends { name: string } 来限定泛型 T 必须具有一个 name 属性,否则会在调用时报错。

  1. 使用多个泛型约束:
function combine<T extends string, U extends string>(a: T, b: U): string {return a + b;
}const result = combine("Hello, ", "TypeScript"); // result的值是 "Hello, TypeScript"

在这个例子中,使用 extends string 来限定泛型 TU 必须是 string 类型,确保只有 string 类型的参数可以传入函数 combine 中。

  1. 使用接口约束泛型:
interface Lengthwise {length: number;
}function printLength<T extends Lengthwise>(obj: T) {console.log(obj.length);
}printLength("Hello"); // 输出: 5
printLength([1, 2, 3]); // 输出: 3

在这个例子中,使用 extends Lengthwise 来限定泛型 T 必须满足 Lengthwise 接口,即必须有一个 length 属性。

interface 与 type 区别

在 TypeScript 中,interfacetype 是两种用来定义类型的方式,它们有一些相似之处,但也有一些不同之处。下面是它们的区别:

  1. interface

    • interface 是用来描述对象的形状的类型声明。
    • 它可以用来定义对象的结构,包含属性、方法和索引签名等。
    • interface 可以被合并,当多次定义同名的 interface 时,它们会自动合并为一个。
    interface Person {name: string;age: number;
    }interface Person {gender: string;
    }// 合并后等同于:
    // interface Person {
    //   name: string;
    //   age: number;
    //   gender: string;
    // }
    
  2. type

    • type 是用来定义任意类型的类型别名。
    • 它可以用来定义原始类型、联合类型、交叉类型、函数类型等。
    • type 不能被合并,当多次定义同名的 type 时,会报错。
    • 要合并需要用 & 连接
    type Age = number;type Gender = "male" | "female";type Person = {name: string;age: Age;gender: Gender;
    };type both = Person & Age // 这样将两个类型合并成一个
    
  3. 使用场景:

    • interface 通常用于描述对象的结构,它更适合用于定义对象和类的类型。
    • type 可以定义更复杂的类型,包括联合类型、交叉类型和函数类型等,它更适合用于定义临时的类型别名。

相关文章:

TypeScript使用技巧

文章目录 使用技巧TypeScript内置的工具类型keyofextends 限定泛型interface 与 type 区别 TypeScript作为JavaScript的超集,通过提供静态类型系统和对ES6新特性的支持,使JavaScript开发变得更加高效和可维护。掌握TypeScript的使用技巧,可以帮助我们更好地开发和组织JavaScrip…...

MySQL — InnoDB事务

文章目录 事务定义事务特性事务隔离级别READ UNCOMMITTEDREPEATABLE READREAD COMMITTEDSERIALIZABLE 事务存在的问题脏读&#xff08;Dirty Read&#xff09;不可重复读&#xff08;Non-repeatable Read&#xff09;幻读&#xff08;Phantom Read&#xff09; 事务定义 数据库…...

LeetCode 42. 接雨水(动态规划 / 单调栈)

题目&#xff1a; 链接&#xff1a;LeetCode 42. 接雨水 难度&#xff1a;困难 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2…...

顺序表、链表刷题指南(力扣OJ)

目录 前言 题目一&#xff1a;删除有序数组中的重复项 思路&#xff1a; 题解&#xff1a; 题目二&#xff1a;合并两个有序数组 思路&#xff1a; 分析&#xff1a; 题解&#xff1a; 题目三&#xff1a;反转链表 思路&#xff1a; 分析&#xff1a; 题解&#xff1a; 题目四&…...

Lambda表达式总结

Lambda作为Java8的新特性&#xff0c;本篇文章主要想总结一下常用的一下用法和api 1.接口内默认方法实现 public interface Formula {double calculate(int a);// 默认方法default double sqrt(int a) {return Math.sqrt(a);} }public static void main(String[] args) {Form…...

岛屿的最大面积

给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。 岛屿的面积是岛上值为 1 …...

迭代器模式(Iterator)

迭代器模式是一种行为设计模式&#xff0c;可以在不暴露底层实现(列表、栈或树等)的情况下&#xff0c;遍历一个聚合对象中所有的元素。 Iterator is a behavior design pattern that can traverse all elements of an aggregate object without exposing the internal imple…...

Goland搭建远程Linux开发

Windows和Linux都需要先构建好go环境&#xff0c;启用ssh服务。 打开Windows上的Goland&#xff0c;建立项目。 点击添加配置&#xff0c;选择go构建 点击运行于&#xff0c;选择ssh 填上Linux机器的IP地址和用户名 输入密码 没有问题 为了不让每次运行程序和调试程序都生…...

react中PureComponent的理解与使用

一、作用 它是一个纯组件&#xff0c;会做一个数据的浅比较&#xff0c;当props和state没改变的时候&#xff0c;不会render重新渲染&#xff0c; 改变后才会render重新渲染&#xff0c;提高性能。 二、使用 三、注意 它不能和shouldComponentUpdate生命周期同时使用。因为它…...

洛谷——P5714 【深基3.例7】肥胖问题

文章目录 题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 AC代码 题目 题目描述 BMI 指数是国际上常用的衡量人体胖瘦程度的一个标准&#xff0c;其算法是 m h 2 \dfrac{m}{h^2} h2m​&#xff0c;其中 m m m 是指体重&am…...

Mac隐藏和显示文件

由于之前没有使用过Mac本&#xff0c;所以很多地方都不太清楚&#xff0c;在下载git项目的时候&#xff0c;发现没有.git文件&#xff0c; 一开始还以为下载错了&#xff0c;但是git命令是可以看到远端分支以及当前分支的&#xff0c;之后在一次解压文件的时候发现&#xff0c;…...

软件工程中应用的几种图辨析

【软件工程】软件工程中应用的几种图辨析&#xff1a;系统流程图、数据流图、数据字典、实体联系图、状态转换图、层次方框图、Warnier图、IPO图、层次图、HIPO图、结构图、程序流程图、盒图、PAD图、判定表_眩晕李的博客-CSDN博客 软件工程——实体关系图 状态转换图 数据流…...

下载离线版的VS Visual Studio 并下载指定的版本

一、先下载引导程序 下载地址VS VisualStudio官网 在这个页面翻到最下面 在这里下载需要的版本 下载引导程序 二、下载离线安装包 写一个批处理文件&#xff08;vs.bat&#xff09; 命令格式如下 <vs引导程序exe> --layout <离线安装包下载的路径> --add <功能…...

Eureka 学习笔记5:InstanceRegistry

版本 awsVersion ‘1.11.277’ LeaseManager 接口管理实例的租约信息&#xff0c;提供以下功能&#xff1a; 注册实例取消注册实例实例续约剔除过期实例 public interface LeaseManager<T> {/** 注册实例并续约*/void register(T r, int leaseDuration, boolean isRep…...

System Verilog——虚方法的使用

1、使用虚方法目的 通过在父类里定义虚方法(task or function)&#xff0c;可以在当父类句柄调用一个方法时候&#xff0c;前提是若是这个句柄指向了子类对象&#xff0c;则调用的方法为子类的方法而不是父类的方法。 1.1、实例理解&#xff1a;将子类句柄赋值成父类句柄 mod…...

线性规划和单纯形法-原理篇

文章目录 引言线性规划标准型问题特点单纯形法 引言 很多运筹学的教材都是从线性规划开始的&#xff0c;我平时做算法策略的落地应用时也研发了一部分基于线性规划的技术方案。可以说&#xff0c;如果搞不懂线性规划&#xff0c;很难成为一名优秀的运筹优化算法工程师。 但是…...

FBX SDK开发快速上手指南

一段时间以来&#xff0c;我一直想制作一个 FBX Exporter 将 FBX 文件转换为我自己的格式。 整个过程不是很顺利&#xff0c;主要是FBX的官方文档不是很清楚。 另外&#xff0c;由于 FBX 格式被许多应用程序使用&#xff0c;而不仅仅是游戏引擎&#xff0c;因此提供的示例代码没…...

探讨|使用或不使用机器学习

动动发财的小手&#xff0c;点个赞吧&#xff01; 机器学习擅长解决某些复杂问题&#xff0c;通常涉及特征和结果之间的困难关系&#xff0c;这些关系不能轻易地硬编码为启发式或 if-else 语句。然而&#xff0c;在决定 ML 是否是当前给定问题的良好解决方案时&#xff0c;有一…...

Git笔记--Ubuntu上传本地项目到github

目录 1--基本配置 2--本地上传 1--基本配置 ① 创建ssh-key cd ~/.sshssh-keygen -t rsa -C "邮箱地址"② 查看并关联ssh-key gedit id_rsa.pub 复制内容&#xff0c;在 GitHub 中依次点击 Settings -> SSH and GPG keys -> New SSH key&#xff0c;将 id…...

基于Go编写一个可视化Navicat本地密码解析器

前提 开发小组在测试环境基于docker构建和迁移一个MySQL8.x实例&#xff0c;过程中大意没有记录对应的用户密码&#xff0c;然后发现某开发同事本地Navicat记录了根用户&#xff0c;于是搜索是否能够反解析Navicat中的密码掩码&#xff08;这里可以基本断定Navicat对密码是采用…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...