这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
Typescript
什么是Typescript?
-
Typescript(简称TS)是JavaScript的超集(JS有的TS都有)
-
Typescript = Type + JavaScript(是在JS的基础上,为JS添加了类型支持)
let age : number = 18
TS相比JS有何优势?
- 减少找Bug、改Bug时间
- 程序中任何位置的代码都有代码提示,随时随地的安全感,增强了开发体验。
- 强大的类型系统提升了代码的可维护性,使得重构代码更加容易。
- 支持最新的ECMAScript语法,优先体验最新的语法,让你走在前端技术的最前沿。
- TS类型推断机制,不需要在代码中的每个地方都显示标注类型,让你在享受优势的同时,尽量降低了成本。
除此之外,Vue3源码使用TS重写、Angular默认支持TS、React与TS完美配合,TypeScript已成为大中型前端项目的首先编程语言。
TypeScript常用类型
JS已有类型
- 原始类型:number/string/boolean/null/undefined/symbol
- 对象类型:object(包括:数组、对象、函数等)
TS新增类型
- 联合类型、自定义类型(类型别名)、接口、元组、字面量类型、枚举、void、any等。
// 原始类型
let age : number = 18
let name : string = "猫猫"
let isLoading : boolean = false
//数组类型
//第一种写法:
let numbers : number[] = [1,2,3]
//第二种写法
let strings : Array<string> = ['a','b','c']
//联合数组类型
let arr : (number | string)[] = [1,'a',2,'b']
类型别名
指为任意类型起别名
- 使用type关键字来创建类型别名
- 类型别名可以使任意合法的变量名称
- 创建类型别名后,直接使用该类型别名作为变量的类型注解即可。
type CustomArray = (number | string)[]
// let arr : (number | string)[] = [1,'a',2,'b']
let arr : CustomArray = [1,'a',2,'b']
函数类型
函数类型实际上指的是:函数参数和返回值的类型。
为函数指定类型的两种方式:
单独指定参数、返回值的类型
// 第一种方式
function add(num1 : number, num2 : number) : number {
return num1 + num2;
}
// 第二种方式
const add1 = (num3 : number, num4 : number) : number => {
return num3 + num4;
}
同时指定参数、返回值的类型
const add2: (num5 : number, num6 : number) => number (num5,num6) => {
return num5 + num6;
}
-
函数没有返回值,返回值类型为:void
function greet(name : string) : void { console.log('hello',name); }可选参数
在可传不可传的参数名称后面添加 “?”
注意:可选参数只能出现在参数列表的最后,必选参数后面不能再出现可选参数了
对象类型
JS中的对象是由属性和方法构成的,而TS中对象的类型就是在描述对象的结构(有什么类型的属性和方法。
let person : {name : string, age : number, sayHi() : void } = {
name: 'Jack',
age : 98,
sayHi() {}
}
可选属性
比如我们在axios({...})时,如果发送GET请求,method属性就可以省略
function myAxios(config: {url : string ; method?: string}) {
console.log(config)
}
接口
当一个对象类型被多次使用是,一般会使用接口(interface)来描述对象的类型,达到复用的目的。
interface IPerson {
name : string
age :number
sayHi() : void
}
let person : IPerson = {
name : 'Jack',
age: 19,
sayHi() {}
}
interface(接口)和type(类型别名)的对比:
-
相同点:都可以给对象指定类型
-
不同点
接口,只能为对象指定类型
类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名。
typy IPerson = {
name : string
age : number
sayHi() : void
}
接口继承
如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承实现复用。例如:
interface Point2D {
x : number
y : number
}
// interface Point3D {
// x : number
// y : number
// z : number
// }
// 也可以这样写
interface Point3D extends Point2D {
z : number
}
元组
元组类型可以确切地标记出有多少个元素,以及每个元素的类型
let position : [number, number] = [39.01,40,2]
类型推论(能省略类型注解的地方就省略)
声明变量并立即初始化值,此时可以省略类型注解
如果声明变量但没有立即初始化值,此时还必须手动添加类型注解
类型断言
- 使用as关键字实现类型断言
- 关键字as后面的类型是一个更加具体的类型(HTMLAnchorElement)
- 通过类型断言,aLink的类型变得更加具体,这样就可以访问a标签特有的属性或方法了
const aLink = document.getElementById('link') as HTMLAnchorElement
aLink.href
字面量类型
// 这个变量是字符串类型
let str1 = "hello Ts"
//这个变量是"hello Ts"类型
const str2 = "hello Ts"
枚举
定义一组命名常量。它描述一个值,该值可能是这些命名常量中的一个。
- 使用enum关键字定义枚举
- 约定枚举名称、枚举中的值以大写字母开头
- 枚举中的多个值之间通过逗号分隔
- 定义好枚举后,直接使用枚举名称作为类型注解
- 类似于JS中的对象,直接通过"."语法访问枚举的成员
enum Direction {Up, Down, Left, Right}
function changeDirection(direction : Direction {
cosole.log(direction)
}
注意:枚举成员是有值的,默认为从0开始自增的
枚举成员的值为数字的枚举称为数字枚举。(同理,可得到字符串枚举)
当然 也可以给枚举的成员初始化值
enum Direction { Up = 10, Down, Left, Right }
enum Direction { Up = 2, Down = 4, Left = 6, Right = 8}
枚举类型的特点:
any类型
原则:不推荐使用any!
typeof操作符
可以根据已有变量的值 获取该值的类型
let a : number = 1
console.log(typeof(a))
let p = { x : 1, y : 2}
function fun(point: typeof p){}
fun({ x: 4, y : 100})
let num : typeof p.x
TypeScript高级类型
class类
class Person {
age : number
gender = '男'
}
const p = new Person()
p.age
p.gender
构造函数:
为实例化对象属性初始化
- 成员初始化(比如age:number)后才可以通过this.age来访问实例成员
- 需要为构造函数指定类型注解,否则会被隐式推断为any
- 构造函数不需要返回值类型
实例方法
class Point {
x = 1
y = 2
// 这里可以写任意自定义的方法
scale(n : number) {
this.x *= n
this.y *= n
}
}
const p = new Point()
p.scale(10)
console.log(p.x,p.y);
类的继承
-
extends
class Animal { move() { console.log("走两步……"); } } class Dog extends Animal { name = "二哈" bark() { console.log("汪汪"); } } const d = new Dog() d.move() d.bark() -
implements
interface Singable { sing() : void } class Person implements Singable { sing(): void { console.log("hello"); } }
可见性修饰符
- public:全部可见,默认是public
- protected:仅对其声明所在类和子类中(非实例对象)可见
- private:只在当前类中可见,对实例对象以及子类也是不可见的
只读修饰符readonly
- 用来防止在构造函数之外对属性进行赋值,相当于把对象属性变成常量
- 只能修饰属性不能修饰方法