前端 -- Typescript快速入门

1、TypeScript 是什么

TypeScript(简称:TS)是 JavaScript 的超集,为 JS 添加了类型支持。
对于 JS 来说:需要等到代码真正去执行的时候才能发现错误(晚)。
对于 TS 来说:在代码编译的时候(代码执行前)就可以发现错误(早)。

2、编译执行typescript

Node.js/浏览器,只认识 JS 代码,不认识 TS 代码。需要先将 TS 代码转化为 JS 代码,然后才能运行。安装命令:npm i -g typescript,验证是否安装成功:tsc –v。

  1. 创建 demo.ts 文件
  2. 将 TS 编译为 JS:在终端中输入命令,tsc demo.ts
  3. 执行 JS 代码:在终端中输入命令,node demo.js。

使用 ts-node 包,npm i -g ts-node 可以直接在 Node.js 中执行 TS 代码。
直接执行 ts-node demo.ts。

3、TypeScript 常用类型

可以将 TS 中的常用基础类型细分为两类:1 JS 已有类型 2 TS 新增类型。

  1. JS 已有类型
    原始类型:number/string/boolean/null/undefined/symbol。
    对象类型:object(包括数组、对象、函数等对象)。
  2. TS 新增类型
    联合类型、自定义类型(类型别名)、接口、元组、字面量类型、枚举、void、any 等

4、类型说明

1. 原始类型

原始类型:number/string/boolean/null/undefined/symbol。
特点:简单。这些类型,完全按照 JS 中类型的名称来书写

let age:number = 18
let name: string = '小明'
let isloading :boolean = false

2. 数组类型

数组类型的两种写法:(推荐使用 number[] 写法)

let numbers: number[] = [1,3,5]
let string: Array<string> = ['a','b','c']

数组中既有number类型,又有string类型

let numbers: (number|string)[] = [1,3,5,'a','b']

3. 函数类型

函数的类型实际上指的是:函数参数和返回值的类型。
为函数指定类型的两种方式:1 单独指定参数、返回值的类型 2 同时指定参数、返回值的类型。

  1. 单独指定参数、返回值的类型:在这里插入图片描述在这里插入图片描述
  2. 同时指定参数、返回值的类型
    在这里插入图片描述

如果函数没有返回值,那么,函数返回值类型为:void
在这里插入图片描述
可选参数:在可传可不传的参数名称后面添加 ?(问号)
在这里插入图片描述

4. 对象类型

TS 中对象的类型就是在描述对象的结构
在这里插入图片描述
同样可以使用可选属性?,可选属性需要排在必先属性后面。

5. 类型别名和接口

类型别名(自定义类型):为任意类型起别名。
使用场景:当同一类型(复杂)被多次使用时,可以通过( type) 类型别名,简化该类型的使用。
在这里插入图片描述

接口:当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的
在这里插入图片描述

interface(接口)和 type(类型别名)的对比:

相同点:都可以给对象指定类型。
不同点:接口,只能为对象指定类型。类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名。

接口继承

如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承来实现复用。

在这里插入图片描述

6. 元组

元组类型是另一种类型的数组,它确切地知道包含多少个元素,以及特定索引对应的类型。
在这里插入图片描述

7.类型推断和类型断言

类型推断:TS 的类型推论机制会帮助提供类型,发生类型推论的 2 种常见场景:1 声明变量并初始化时 2 决定函数返回值时。
在这里插入图片描述
类型断言:有时候你会比 TS 更加明确一个值的类型,此时,可以使用类型断言来指定更具体的类型。
在这里插入图片描述

在浏览器控制台,通过 console.dir() 打印 DOM 元素,在属性列表的最后面,即可看到该元素的类型。

8. 字面量类型

let str1 = 'hello TS'
const str2 = 'hello TS'
  1. str1 是一个变量(let),它的值可以是任意字符串,所以类型为:string。
  2. str2 是一个常量(const),它的值不能变化只能是 ‘Hello TS’,所以,它的类型为:‘Hello TS’。

此处的 ‘Hello TS’,就是一个字面量类型。也就是说某个特定的字符串也可以作为 TS 中的类型。 除字符串外,任意的 JS 字面量(比如,对象、数字等)都可以作为类型使用。

字面量类型可以配合联合类型一起使用
在这里插入图片描述

9.枚举

枚举:定义一组命名常量。它描述一个值,该值可以是这些命名常量中的一个。

在这里插入图片描述

注意:枚举成员是有值的,默认为:从 0 开始自增的数值,枚举成员的值为数字的枚举,称为:数字枚举。
在这里插入图片描述
也可以给枚举中的成员初始化值
在这里插入图片描述

枚举转换格式,如下:在这里插入图片描述

10. any类型

当值的类型为 any 时,可以对该值进行任意操作,并且不会有代码提示。
原则:不推荐使用 any!这会让 TypeScript 变为 “AnyScript”(失去 TS 类型保护的优势)。

11. typeof

typeof 操作符,用来在 JS 中获取数据的类型,TS 也提供了 typeof 操作符:可以在类型上下文中引用变量或属性的类型(类型查询)。
在这里插入图片描述

4、TypeScript 高级类型

1、class 类

TS 中的 class,不仅提供了 class 的语法功能,也作为一种类型存在。在这里插入图片描述

class Person {
	x:number
	age:number
	gender:string
	//成员初始化(比如,age: number)后,才可以通过 this.age 来访问实例成员
	constructor(age:number,gender:string){
		this.age = age
		this.gender = gender
	}
	//方法的类型注解(参数和返回值)与函数用法相同
	add(n:number):void{
		this.x= n
	}
}
class 类的继承

类继承的两种方式:1 extends(继承父类) 2 implements(实现接口)。
说明:JS 中只有 extends,而 implements 是 TS 提供的。

class Animal {
	move(){}
}
class Dog extends Animal {
	bark(){}	
}
class Cat implements Animal{
	run(){}
}
class 类的可见性修饰符
  1. public:表示公有的、公开的,公有成员可以被任何地方访问,默认可见性。
class Animal {
 public	move(){}
}
  1. protected:表示受保护的,仅对其声明所在类和子类中(非实例对象)可见。
class Animal {
 protected move(){}
}
//在子类的方法内部可以通过 this 来访问父类中受保护的成员,但是,对实例不可见!
class Dog extends Animal {
	bark() {
	 	this.move()
	}
}
  1. private:表示私有的,只在当前类中可见,对实例对象以及子类也是不可见的。
class Animal {
	private move(){}
	walk(){
		this.move()
	}
}
  1. readonly:表示只读,用来防止在构造函数之外对属性进行赋值。
class Person {
	readonly age:number = 19
	//注意:属性 age 后面的类型注解(比如,此处的 number)如果不加,则 age 的类型为 18 (字面量类型)。
	constructor(age:number){
		this.age = age
	}
}

2.类型兼容性

TS 采用的是结构化类型系统,也叫做 duck typing(鸭子类型),类型检查关注的是值所具有的形状。 也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。

1.class兼容性
class Point {x:number; y:number}
class Point2D {x:number;y:number}
const p:Point = new Point2D()

更准确的说法:对于对象类型来说,y 的成员至少与 x 相同,则 x 兼容 y(成员多的可以赋值给少的)。

class Point {x:number; y:number}
class Point3D {x:number;y:number;z:number}
const p:Point = new Point3D()
2.接口兼容性

接口兼容性与class类似
在这里插入图片描述

3. 函数兼容性

函数之间兼容性比较复杂,需要考虑:1 参数个数 2 参数类型 3 返回值类型

  1. 参数个数,参数多的兼容参数少的(或者说,参数少的可以赋值给多的)例如数组forEach
    在这里插入图片描述
  2. 参数类型,相同位置的参数类型要相同(原始类型)或兼容(对象类型)
    在这里插入图片描述
  3. 返回值类型,只关注返回值类型本身即可:
    如果返回值类型是原始类型,此时两个类型要相同,如果返回值类型是对象类型,此时成员多的可以赋值给成员少的。
    在这里插入图片描述

3、交叉类型

交叉类型(&):功能类似于接口继承(extends),用于组合多个类型为一个类型(常用于对象类型)。
在这里插入图片描述
使用交叉类型后,新的类型 PersonDetail 就同时具备了 Person 和 Contact 的所有属性类型。
相当于:
在这里插入图片描述
交叉类型(&)和接口继承(extends)的对比:
相同点:都可以实现对象类型的组合。
不同点:两种方式实现类型组合时,对于同名属性之间,处理类型冲突的方式不同。
在这里插入图片描述
结果:接口继承会报错(类型不兼容);交叉类型没有错误。

4、泛型

泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class 中。

function id<T>(value:T):T { return value }
const num = id<number>(10)
const str = id<string>('a')
//简化写法:在调用泛型函数时,可以省略 <类型> 来简化泛型函数的调用
let num2 = id(10)
  1. 语法:在函数名称的后面添加 <>(尖括号),尖括号中添加类型变量,比如此处的 Type。
  2. 类型变量 Type,是一种特殊类型的变量,它处理类型而不是值。
  3. 该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)。
  4. 因为 Type 是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型。
  5. 类型变量 Type,可以是任意合法的变量名称
1.泛型约束

默认情况下,泛型函数的类型变量 Type 可以代表多个类型,这导致无法访问任何属性
比如,id(‘a’) 调用函数时获取参数的长度:
在这里插入图片描述

添加泛型约束收缩类型
  • 指定更加具体的类型
    在这里插入图片描述
    比如,将类型修改为 Type[](Type 类型的数组),因为只要是数组就一定存在 length 属性,因此就可以访问了。
  1. 添加约束
  • 创建描述约束的接口 ILength,该接口要求提供 length 属性。
  • 通过 extends关键字使用该接口,为泛型(类型变量)添加约束。
  • 该约束表示:传入的类型必须具有 length 属性。
    在这里插入图片描述
  • 添加了第二个类型变量 Key,两个类型变量之间使用(,)逗号分隔。
  • keyof 关键字接收一个对象类型,生成其键名称(可能是字符串或数字)的联合类型。
  • 本示例中 keyof Type 实际上获取的是 person 对象所有键的联合类型,也就是:‘name’ | ‘age’。
  • 类型变量 Key 受 Type 约束,可以理解为:Key 只能是 Type 所有键中的任意一个,或者说只能访问对象中存在的属性。
    在这里插入图片描述
2.泛型接口

接口也可以配合泛型来使用,以增加其灵活性,增强其复用性
在这里插入图片描述

实际上,JS 中的数组在 TS 中就是一个泛型接口。
当我们在使用数组时,TS 会根据数组的不同类型,来自动将类型变量设置为相应的类型。
在这里插入图片描述

3.泛型类

class 也可以配合泛型来使用
在这里插入图片描述

4、泛型工具类型

泛型工具类型:TS 内置了一些常用的工具类型,来简化 TS 中的一些常见操作。

  1. Partial 用来构造(创建)一个类型,将 Type 的所有属性设置为可选。
    在这里插入图片描述

这里 PartialProps 为

{
	id?:string
	children?:number[]
}
  1. Readonly 用来构造一个类型,将 Type 的所有属性都设置为 readonly(只读)
    在这里插入图片描述
    在这里插入图片描述

构造出来的新类型 ReadonlyProps 结构和 Props 相同,但所有属性都变为只读的。当我们想重新给 id 属性赋值时,就会报错:无法分配到 “id” ,因为它是只读属性。
3. Pick<Type, Keys> 从 Type 中选择一组属性来构造新类型。
在这里插入图片描述
这里PickProps为

{
	id:string
	title:string
}
  1. Record<Keys,Type> 构造一个对象类型,属性键为 Keys,属性类型为 Type。在这里插入图片描述

5. 索引签名类型

使用场景:当无法确定对象中有哪些属性(或者说对象中可以出现任意多个属性),此时,就用到索引签名类型了。
在这里插入图片描述

6. 映射类型

映射类型:基于旧类型创建新类型(对象类型),减少重复、提升开发效率。
比如,类型 PropKeys 有 x/y/z,另一个类型 Type1 中也有 x/y/z,并且 Type1 中 x/y/z 的类型相同,像这种情况,就可以使用映射类型来进行简化。
在这里插入图片描述

Key in PropKeys 表示 Key 可以是 PropKeys 联合类型中的任意一个,类似于 forin(let k in obj)。

映射类型除了根据联合类型创建新类型外,还可以根据对象类型来创建:
在这里插入图片描述

1.基于映射类型实现 - 泛型工具类型

泛型工具类型(比如,Partial)都是基于映射类型实现的。 比如,Partial 的实现:
在这里插入图片描述
T[P] 表示获取 T 中每个键对应的类型。比如,如果是 ‘a’ 则类型是 number;如果是 ‘b’ 则类型是 string。

2.索引查询(访问)类型

例如以上用到的 T[P] 语法,用来查询属性的类型。在这里插入图片描述
也可以用Props[‘a’] 表示查询类型 Props 中属性, ‘a’ 对应的类型 number。所以,TypeA 的类型为 number。
支持同时查询多个索引的类型:

使用字符串字面量的联合类型,获取属性 a 和 b 对应的类型,结果为: string | number。
在这里插入图片描述
使用 keyof 操作符获取 Props 中所有键对应的类型,结果为: string | number | boolean。
在这里插入图片描述

5. typescript类型声明文件

1.TS 中的两种文件类型

  • .ts 文件:
  1. 既包含类型信息又可执行代码。
  2. 可以被编译为 .js 文件,然后,执行代码。
  3. 用途:编写程序代码的地方。
  • .d.ts 文件:
  1. 只包含类型信息的类型声明文件。
  2. 不会生成 .js 文件,仅用于提供类型信息。
  3. 用途:为 JS 提供类型信息。
    总结:.ts 是 代码实现文件;.d.ts 是类型声明文件

2.类型声明文件场景

  1. 内置类型声明文件:TS 为 JS 运行时可用的所有标准化内置 API 都提供了声明文件。
    比如,在使用数组时,数组所有方法都会有相应的代码提示以及类型信息:
    在这里插入图片描述
  2. 第三方库的类型声明文件:目前,几乎所有常用的第三方库都有相应的类型声明文件。
    库自带类型声明文件:比如,axios。 如果使用的第三方库没有自带的声明文件,VSCode 会给出明确的提示。
    在这里插入图片描述
    当安装 @types/* 类型声明包后,TS 也会自动加载该类声明包,以提供该库的类型声明。

3.创建自己的类型声明文件

1.新建的类型声明文件
  1. 创建 index.d.ts 类型声明文件。
  2. 创建需要共享的类型,并使用 export 导出(TS 中的类型也可以使用 import/export 实现模块化功能)。
  3. 在需要使用共享类型的 .ts 文件中,通过 import 导入即可(.d.ts 后缀导入时,直接省略)
2. 为已有 JS 文件提供类型声明

在导入 .js 文件时,TS 会自动加载与 .js 同名的 .d.ts 文件,以提供类型声明。

declare 关键字:用于类型声明,为其他地方(比如,.js 文件)已存在的变量声明类型,而不是创建一个新的变量。

  1. 对于 type、interface 等这些明确就是 TS 类型的(只能在 TS 中使用的),可以省略 declare 关键字。
  2. 对于 let、function 等具有双重含义(在 JS、TS 中都能用),应该使用 declare 关键字,明确指定此处用于类型声明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值