ts笔记


TypeScript(TS)是 JavaScript 的超集,在 JS 基础上添加类型支持,是微软开发的开源编程语言,可在任何运行 JavaScript 的地方运行,如let age1: number = 18(TS 代码)和let age2 = 18(JS 代码)对比,TS 有明确类型标注。
2. 添加类型支持的原因
JS 类型系统存在缺陷,多数错误为类型错误,影响开发效率。TS 属于静态类型编程语言,在编译期做类型检查;JS 属于动态类型编程语言,执行期做类型检查。TS 能在编译时(执行前)发现错误,配合开发工具可在编写代码时发现错误,减少找 Bug 和改 Bug 时间。
3. 优势
更早发现错误,提升开发效率;提供代码提示,增强开发体验;提升代码可维护性,便于重构;支持最新 ECMAScript 语法;有类型推断机制,降低使用成本。在多个前端框架中广泛应用,是大中型前端项目首选编程语言。
4. 初体验
环境搭建:Node.js 和浏览器只识别 JS 代码,需安装typescript包(npm i -g typescript)将 TS 转化为 JS,通过tsc -v验证安装,tsc命令实现转化。
运行 TS 代码
传统方式:创建.ts文件,用tsc命令编译生成.js文件,再用node命令执行。
简化方式:安装ts-node包(npm i -g ts-node),用ts-node命令直接运行 TS 文件,内部自动完成转化。
二、常用类型系统
1. 类型注解与类型推论
类型注解:为变量、函数参数、返回值、对象属性和方法等添加类型约束,如let age: number = 18中: number为类型注解,约定变量类型,赋值不符会报错。
//Typescript代码中有明确的类型,即:number(数值类型)
let age:number=23;

//JavaScript代码,无明确的类型
let age2=23;
类型推论:在声明变量并初始化或决定函数返回值时,TS 自动推断类型,可省略类型注解,如let age = 18(TS 推断age为number类型)。推荐省略能省略的类型注解,利用 VSCode 提示查看类型。

2. 常用基础类型
原始类型:包括number、string、boolean、null、undefined、symbol,书写与 JS 中类型名称一致,如Let age: number = 18。
数组类型:推荐number[]写法,也可用Array<string>。元素包含多种类型时,用联合类型表示,如Let arr: (number | string)[] = [1, 'a', 3, 'b'],注意与 JS 中或(||)的区别。
//创建数组的方式
const arr1:string[]=[]
const arr:number[]=[1,2,3]
const arr2:Array<string> = ['basketball','football']
//数组的使用
const arr:number[]=[1,2,3,4,5]//创建一个number类型的数组
const arr1:String[]=["wcr","zs","fcc"]//创建一个string类型的数组
console.log(arr1.length);//得到长度3
console.log(arr1[0]);//取值,得到wcr
//遍历数组arr,从0号索引开始,最大的长度是length-1
for(let i:number=0;i<arr.length-1;i++){
console.log(arr[i]);
}
类型别名(自定义类型):使用type关键字为复杂类型创建别名简化使用,如type CustomArray = (number | string)[],之后可直接用别名作为变量类型注解。可以提高开发效率,避免多次写重复的代码。
//类型别名 type
type numtype= number|string|null|Array<String|number>
//联合类型
const num:numtype=123
const A:numtype='123'
const B:numtype=null
const C:numtype=[1,2,3]
3. 函数类型
参数与返回值类型指定
单独指定:

同时指定(函数表达式):

特殊情况
无返回值时函数返回值类型为void
function greet(name:string):void{
console.log('hello',name);
}
可选参数:参数可传可不传时,在参数名后加?,且必须在参数列表末尾

4. 对象类型
是用来描述对象结构的


解释:
1. 直接使用 {} 来描述对象结构。属性采用 属性名: 类型 的形式;方法采用 方法名(): 返回值类型 的形式。
2. 如果方法有参数,就在方法名后面的小括号中指定参数类型(比如: greet(name: string): void )。
3. 在一行代码中指定对象的多个属性类型时,使用 ;(分号)来分隔。
l 如果一行代码只指定一个属性类型(通过换行来分隔多个属性类型),可以去掉 ;(分号)。
l 方法的类型也可以使用箭头函数形式(比如:{ sayHi: () => void })。
5. 接口:
一般使用interface表示接口,是用来达到复用的目的。

interface Iperson{
name:string;
age:number;
sayHi():void;
}

let person:Iperson={
name:'jack',
age:12,
sayHi(){
console.log('hi');
}
}
//解释:
//1. 使用 interface 关键字来声明接口。
//2. 接口名称(比如,此处的 IPerson),可以是任意合法的变量名称。
//3. 声明接口后,直接使用接口名称作为变量的类型。
//4. 因为每一行只有一个属性类型,因此,属性类型后没有 ;(分号)。

//接口和类型别名的区别:二者都是给对象指定类型的;但是接口是给对象指定类型的,类型别名可以为任一类型指定别名。

同时,接口也具有继承的特性,使用extends关键字。

 

6. 元组
用于确切知道数组元素个数和特定索引对应类型的场景

 

7. 类型断言
当 TS 推断类型不能满足需求时,使用类型断言指定更具体类型

//定义一个cat的接口
interface cat{
name:string,
age:number,
run:()=>void
}

//定义一个dog的接口
interface dog{
name:string,
eat:()=>void
}

//将一个父类断言为子类,首先animals
//可以是cat或者dog类型。
function animal(animals:cat|dog){
//将animals断言为cat类型,那它具有cat
//的属性和方法。
console.log((animals as cat).age);

}
//此时name为dog的类型就具有cat的age属性,为2
console.log({name:"dog",age:2});

8. 字面量类型
let str='Hello TS'

function changeDirection(direction: 'left' | 'right'|'top'|'bottom') {
console.log(direction);
}
总结:特定的字符串、数字等字面量可作为类型,如str类型为'Hello TS'。常与联合类型配合使用,表示一组明确的可选值列表,如函数参数direction只能取'left' |'right'|'top'|'bottom'中的值,相比string类型更精确严谨。

9. 枚举
enum Direction1{//默认值从0开始,递增
up=8,
down,
left,
right
}

enum Direction2{
//字符串枚举,枚举成员的值是字符串,
// 注意: 字符串枚举没有自增长行为,因此,字符串枚举的每个成员必须有初始值。
up='UP',
down='down',
left='left',
right='right'
}
const a:Direction1=Direction1.up
console.log(a);//8

const c:Direction2=Direction2.up
console.log(c);/UP

总结:
1. 使用enum关键字定义枚举
2. 约定枚举名称、枚举中的值以大写字母开头
3. 枚举中的多个值之间通过 ,(逗号)分隔
4. 定义好枚举后,形参直接使用枚举名称作为类型注解
5. 实参的值可以是枚举 Direction 成员的任意一个,接通过点(.)语法访问枚举的成员
6. 从输出结果为0,我们可以知道表示枚举的值是会携带默认值的,从 0 开始自增的数值
7. 通过扩展1能知道数字的起始值可以自定义,并且自增只针对数字类型
8. 枚举中的成员也可以自定义初始化值

10. any 类型


原则上不推荐使用,会使 TS 失去类型保护优势。

解释:以上操作无类型错误提示,但可能存在错误。其他隐式具有any类型的情况有声明变量不提供类型也不提供默认值、函数参数不加类型,应尽量避免使用,除非临时用于 “避免” 书写复杂类型。

11. typeof
在 TS 中,typeof可在类型上下文中引用变量或属性的类型(类型查询),用于根据已有变量的值获取其类型简化类型书写。

 

 

解释:
1. 使用 typeof 操作符来获取变量 p 的类型,结果与第一种(对象字面量形式的类型)相同。
2. typeof 出现在 类型注解的位置 (参数名称的冒号后面) 所处的环境就在类型上下文 (区别于 JS 代码)。
3. 注意:typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函数调用的类型)。
三、高级类型特性
1. class
TS 全面支持class关键字,为其添加类型注解和其他语法(如可见性修饰符等)。
实例属性初始化:
class Person{
age:number;
gender='男'
//gender:string='男'
}
//解释:
//1. 声明成员 age,类型为 number(没有初始值)。
//2. 声明成员 gender,并设置初始值,此时,可省略类型注解(TS 类型推论 为 string 类型)。
构造函数:成员初始化后才能在构造函数中通过this访问,构造函数需指定类型注解,无返回值类型。
class Person{
age:number
gender:string

constructor(age:number,gender:string){
this.age=age
this.gender=gender
}
}
实例方法:方法类型注解与函数用法相同
类继承:有extends(继承父类)和implements(实现接口)两种方式。
extends实现继承,子类继承父类后拥有父类和子类所有属性和方法,
implements使类必须实现接口中指定的方法和属性。
类成员可见性:包括public(公有的,默认可见性)、protected(受保护的,仅对声明所在类和子类中(非实例对象)可见)、private(私有的,只在当前类中可见)和readonly(只读修饰符,防止在构造函数之外对属性赋值,只能修饰属性不能修饰方法)。
2. 泛型
可在保证类型安全前提下让函数等与多种类型一起工作实现复用,常用于函数、接口、class中。
创建泛型函数:语法为在函数名后加<>尖括号,尖括号内为类型变量(可自定义名称),类型变量作为函数参数和返回值类型,表示参数和返回值具有相同类型,如function id<Type>(value: Type): Type { return value; }。
调用泛型函数:可在函数名后<>指定具体类型,也可省略(TS 会根据传入实参自动推断类型变量类型),如const num = id<number>(10); const str = id('a'); let num = id(10);,推荐省略简化调用,但编译器无法推断或推断不准确时需显式传入类型参数。
泛型约束:默认泛型函数类型变量可代表多种类型,可能无法访问属性,需添加约束收缩类型,可指定更具体类型(如Type[])或添加约束(通过extends关键字使用接口约束类型变量,要求传入类型必须具有指定属性),泛型的类型变量可多个且相互约束,如function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) { return obj[key]; }。
泛型接口:接口名称后加<类型变量>变为泛型接口,类型变量对接口所有成员可见,使用时需显式指定具体类型,如interface IdFunc<Type> { id: (value: Type) => Type; ids: () => Type; } let obj: IdFunc<number> = { id(value) { return value; }, ids() { return [1, 3, 5]; } },JS 中的数组在 TS 中是泛型接口,TS 会根据数组类型自动设置类型变量。
泛型类:class名称后加<类型变量>变为泛型类,创建实例时需在类名后<>指定明确类型,如class GenericNumber<NumType> { defaultValue: NumType; add: (x: NumType, y: NumType) => NumType; } const myNum = new GenericNumber<number>()。
泛型工具类型:TS 内置基于泛型实现的工具类型,如Partial<Type>(将Type所有属性设为可选)、Readonly<Type>(将Type所有属性设为只读)、Pick<Type, Keys>(从Type中选一组属性构造新类型)、Record<Keys, Type>(构造对象类型,属性键为Keys,属性类型为Type)。

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

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

相关文章

解决explorer文件丢失黑屏

下载火绒后会把explorer.exe判断为病毒并隔离; 第一种方法可以用任务管理器找到火绒安装路径的bin目录,运行HpsMain进入火绒的隔离区,找到explorer.exe,点击恢复并加入信任区 第二种方法适用于不小心卸载火绒的情况,有的兄弟可能黑屏后直接删除了火绒,但是这种情况火绒会…

烟火烟雾智能检测摄像机安消系统 守护电动车充电桩安全

电动车充电桩烟火检测系统首先通过高清摄像头对停车场或楼宇充电桩区域进行视频采集。这些摄像头通常覆盖广角区域,具备夜视能力,能够在全天候条件下提供高质量的视频输入。采集的视频数据通过图像去噪、亮度校正等预处理步骤,确保算法输入的稳定性和准确性。近年来,随着电…

AI泥石流智能算法摄像头

山体落石滑坡识别系统 落石泥石流监控摄像机基于YOLOX+RNN的深度学习算法,山体落石滑坡识别系统 落石泥石流监控摄像机通过安装在山区公路沿线的监控摄像机来实现对山体的实时监测。这些摄像机分布在关键位置,如山体易滑坡区域、桥梁附近等,能够24小时不间断地捕捉山体的动态…

ApoorvCTF Rust语言逆向实战

上周参加了国外的ApoorvCTF比赛,看一下老外的比赛跟我们有什么不同,然后我根据国内比赛对比发现,他们考点还是很有意思的,反正都是逆向。上周参加了国外的比赛,名称叫:ApoorvCTF 看一下老外的比赛跟我们有什么不同,然后我根据国内比赛对比发现,他们考点还是很有意思的,…

ACK 通过sls收集pod日志

常见的收集方式 filebeat->kafka->logstash->es阿里云ACK日志收集 ack->sls 这里要说的是我们传统意义上是通过收集pod或者node节点上的 .log日志文件进行收集日志,在ack里面可以不用通过收集.log的方式进行日志收集。具体的操作看下面的步骤1 开始操作吧 1.1 ACK…

GreatSQL5.7 与 8.0 对 DATE 非法值处理方式不同

GreatSQL5.7 与 8.0 对 DATE 非法值处理方式不同 一、问题描述 1. 问题现象 当分别通过LOAD DATA LOCAL INFILE和INSERT导入非法的 DATE 字段数据时,在5.7.21和 8.0.25使用LOAD DATA LOCAL会报一个Warning,数据异常但可以插入成功,而且实际插入的数据跟用户计划插入的不同,…

Hyper-V的安装过程自动化程度较高,但要了解每个安装步骤背后的原理

Hyper-V的安装过程确实具有较高的自动化程度,但了解每个安装步骤背后的原理对于确保安装的成功以及后续的维护和管理至关重要。以下是对Hyper-V安装过程中每个关键步骤及其原理的详细解析:一、准备工作 步骤:检查系统要求、备份数据、关闭不必要的程序。 原理: 系统要求:确…

牛客题解 | 拼凑三角形

牛客题库题解题目 题目链接 题解 题目难度:简单 知识点:数学逻辑 思路: 三角形成立的条件:1.为了更简便的判断三角形是否成立,将三个数由小到大进行排序放入a[3]中,只需要满足a[0]+a[1]&amp;gt;a[2]即可。(两个较小的数相加大于第三个数)。 2.若a[0]+a[1]&amp;…

内网环境部署Deepseek+Dify,构建企业私有化AI应用

0.简介 公司为生产安全和保密,内部的服务器不可连接外部网络,为了可以在内网环境下部署,采用的方案为ollama(Docker)+Dify(Docker Compose),方便内网环境下迁移和备份,下文将介绍部署的全部过程。 1.镜像拉取 镜像拉取为准备工作,因服务器在内网环境,需要先在可以连接外…

牛客题解 | 拍照队形

牛客题库题解题目 题目链接 题解 题目难度:简单难度 知识点:数学逻辑 分析:主要考虑输出格式,由于N=3k+1,那么前K行每行输出2个字符,后k+1行输出1个字符。对于前k行,第一行:第一列输出字符,空格数为m=2*k-1,在输出第二个字符;第二行:先空格1,输出字符,空格m-=2个(…

电动后尾门控制器PLGM

经纬恒润平台化的电动尾门控制器PLGM可为不同的后尾门应用场合提供解决方案,目前已为众多客户配套量产。 经纬恒润平台化的电动尾门控制器PLGM(Power Lift Gate Module,PLGM)可为不同的后尾门应用场合提供解决方案,目前已为众多客户配套量产。主要功能车门电动打开…

CentOS 磁盘扩容lvm(虚拟机环境)

fdisk -l 查看磁盘情况对新增加的硬盘进行分区,使用fdisk命令创建和维护分区表。 fdisk /dev/vda 输入p:查看已分区数量(有两个 /dev/vda1 /dev/vda2) 输入n(new partition):新增加一个分区 输入p(parimary partition):分区类型选择为主分区 输入分区号3(partition …