当前位置: 首页 > 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对密码是采用…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...