【5】【TypeScript】(TypeScript=Type+JavaScript)

Typescript 相比js特有

·类型系统;
·对象的接口
·DOM操作时候需要进行类型断言
上面三个实际是类型系统的三处体现
·枚举
·js中,-号可以强制转换为数值,ts不行

所有合法的js都是ts

1、安装

安装进度卡住可以用淘宝镜像 (在后面加 --registry=http://registry.npm.taobao.org)                     

tsc -v 查看是否安装成功

 2、编译并运行TS代码

手动编译 (注意要把ts文件放在项目目录第一级)

 

 设置类型编译后两个文件产生如下区别

//1.ts

//1.js

总结:

创建ts文件->编译ts->运行js

简化复杂的过程:

1、在idea中勾选这个选项

好像不行

 1、使用ts-node包

安装

直接用ts-node 1.ts运行文件

常用类型概述

更改类型js会报错 只能在运行后才能发现错误

 但是ts就可以在编译时候提示错误

 类型注解:

 此处number为类型注解,作用:为变量添加类型约束,比如,上述代码中,约定变量age的类型为number(数值类型)

数组类型

推荐下图上面的红框里类型+[ ]的写法,下面的写法存在但是不推荐

let numbers: number[] = [1,3,5]
for (let number of numbers) {
    console.log(number);
}

 混合类型:

在括号里用竖线隔开多个类型使得数组中可以出现多种类型的变量

类型别名:

当混合类型很长后,每次书写就不方便,此时可以使用别名代替混合类型

常有基础类型综述:

js原有:

原始类型:

number
string
boolean
null
underfined
symbol

对象类型:object:(包括,数组,对象,函数等对象)

ts新增:

联合类型:

自定义类型(类型别名)

接口

元组
字面量类型
枚举
void

any

原始类型的基本使用:

                  

函数类型

1、单独指定参数、返回值的类型

函数表达式 

 

2、同时指定参数、返回值的类型:

void类型(js中没有)

  

使用函数实现某个功能,参数可传也可以不传:

可选参数:在可传可不传的参数名称后面添加(问号)

注意顺序,可选参数只能排在必选参数后面

对象类型(就是在描述对象的结构)

对象类型的写法 描述对象的属性和方法

let person:{name:string;age:number;sayHi():void}={
    name:'jack',
    age:19,
    sayHi(){}
}

 其中sayHi():void 也可以写成sayHi:()=>void

也可以把括号里分号去掉以换行分割属性

let person:{
    name:string
    age:number
    sayHi():void}={
    name:'jack',
    age:19,
    sayHi(){}
}

对象中的可选属性

与前面函数可选参数一样都是加问号

function myAxios(config:{url:string;method?:string}){}
myAxios({
    url:''
})

接口

描述对象的类型达到复用的目的

实际上就是将对象名后面的括号单独拿出来写成接口

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

let person2:IPerson = {
    name:'jack',
    age:18,
    sayHi() {
    }
}

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

相同点:都可以给对象指定类型

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

interface声明如果重名会自动合并属性,而type声明重复则会报错

type IPerson={
    name:string
    age:number
    sayHi():void
}

let person2:IPerson = {
    name:'jack',
    age:18,
    sayHi() {
    }
}

接口继承:

当接口之间出现重合部分,为了避免复写,可以直接继承父类重复

interface Point2D {x:number;y:number}

interface Point3D extends Point2D{
    z:number
}
let p3:Point3D={
    x:1,
    y:0,
    z:3
}

一个接口继承另外一个接口的含义:这个接口具有父类接口里的所有睡醒和方法

元组类型

当数组中只有两个元素时候,因为数组无法定死数量,所以这时候可以用元组

let position1:[number,number]=[32,8]
let position2:[number,string]=[32,'8']

类型推论:

在Ts中某些场景,类型推论机制会自动识别类型,此时类型注解可以省略不写

并且类型检查和保护机制也存在

发生类型推论的2种常见场景:1声明变量并初始化的时候 2决定函数返回值时候

 如果只声明没有初始化推荐还是手动指定类型

 函数参数的地方一定要写类型,返回类型可以省略

推荐能省略类型就省略类型,充分利用类型推论机制,提高开发效率

类型断言

 由于类型太宽泛,对象无法获取带a标签的href属性值

这时候可以用as关键字来类型断言

const aLink = document.getElementById('link')as HTMLAnchorElement
var href = aLink.href;

另一种方法是在document前面加<>里面写类型

类型可以通过在浏览器里输出标签的对象来查看,也可以直接打比如a标签就是HTML+a的单词类型

字面量类型

思考以下代码,两个变量的类型分别是什么?

let str1 = 'Hello Ts'
const str2 = 'Hello Ts'

我们可以以变量类型的类型声明变量

let str1 = 'Hello Ts'

const str2:'Hello Ts' = 'Hello Ts'

再如我们把数值类型的变量赋给数值

 当数值不是18时将会报错

所以不管是字符还是数值等等都可以作为类型出现,他们有一个统一的名字:字面量类型

但这样做有什么意义呢?

使用模式字面量类型配合联合类型一起使用

使用场景用来表示一组明确的可选值列表

 比如,在贪吃蛇游戏中,游戏的方向的可选值只能是上、下、左、右中的任意一个。

function changeDirection(direction:'up'|'down'|'left'|'riaght'){
    console.log(direction)
}

这时候调用函数,就只能填定义好的类型,使得变量参数不会出错

 

 字面量类型指的是js中的任意的字面值,如字符串,数值等等,字面量在ts中也可以作为类型出现,一般与联合类型一起使用,作用是表示一组明确的可选值列表。

 枚举类型

枚举的功能类似于字面类型+联合类型组合的功能,也可以表示一组明确的可选值。

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

enum Diretion{Up,Down,Left,Right}

function changeDirection(direction:Diretion){
    console.log(direction)
}

changeDirection(Diretion.Right)

于是在Ts 中表示一组可选值,我们拥有两种方案:1、字面量+联合类型,2、枚举类型

我们推荐字面量+联合类型的方式,因为这种方式更加直观、简洁、高效

(枚举类型会编译成js中的对象形式,而字面量+联合类型会直接编译)

枚举成员的值以及数字枚举

注意:枚举成员是有值的,默认为:从0开始自增的数值

我们把,枚举成员的值为数字的枚举,称为:数字枚举

当然,也可以给枚举中的成员初始化值

当给枚举类型中的第一个赋值后,其它值会默认自增

 也可以全部赋值

字符串枚举

枚举成员的值是字符串。

注意:字符串枚举必须要为每个成员都设置初始值

 枚举的特点及原理:

枚举是Ts为数不多的非JavaScript 类型级扩展(不仅仅是类型)的特性之一。

因为:其它类型仅仅被当做类型,而枚举不仅作为类型,还提供值(枚举成员都是有值的)。

也就是说,其它的类型会在编译为JS代码时自动移除。但是,枚举类型会被编译为JS代码!

 编译为js文件后

 我们可以发现在ts中的枚举变异后转换为了js中的对象,枚举的成员作为对象的属性,枚举成员的值作为对象属性的值。

any类型

不推荐使用any 

原因:使用any会让TypeScript变为AnyScript (失去TS的类型保护优势)

当值为any时,可以对该值任意操作,并且不会有代码提示

比如把对象类型赋给数值类型,不会有任何报错提示

any主要用途在于写代码某些时候不知道要用的类型名称,或是名称很复杂,临时使用,但是还是不推荐

其它隐式具有any类型的情况:

1、声明变量不提供类型也不提供默认值

2、函数参数不加类型

注意:因为不推荐使用any,所以,这两种情况下都应该提供类型!

typeof 操作符

js中提供了typeof操作符,用来在js中获取数据的类型。

实际上,TS也提供了typeof操作符:可以在类型上下文引用变量或属性的类型(类型查询)。

使用场景:根据已有变量的值,获取该值的类型,用来简化类型书写。

let p ={x:1,y:2}

function formatPoint(point:{x:number; y:number})


function formatPoint(point: typeof p){
    
}

Typescript高级类型

TS中的高级类型有很多,重点学习以下高级类型:

1、class类    Ts在js基础上增加类型注解和新功能(如成员可见性修饰符)

2、类型兼容类型  表示类型之间的关系

3、交叉类型    类似联合类型   

4、泛型和keyof   泛型让函数和接口更加通用

5、索引签名类型和索引查询类型

6、映射类型

TypeScript全面支持ES2015中引的关键字,并为其添加了类型注解和其他语法(比如,可见性修饰符等)。class基本使用,如下:

实例属性初始化:

有默认值的属性,可以省略属性类型

class Person {
    age: number =10
    gender = '男'

}

const p1= new Person()

console.log(p1.gender)
console.log(p1.age)

 构造函数

class Person {
    age: number =10
    gender = '男'
    constructor(age:number,gender:string) {
        this.age = age
        this.gender = gender
    }

}
const p1= new Person(18,'女')
console.log(p1.gender)
console.log(p1.age)

class实例方法:

//实例方法

class Point {
    x=1
    y=2

    scale(n:number):void {  //void类型括号后面可以省略返回值类型
        this.x*=n
        this.y*=n
    }
}
const p2 = new Point()
p2.scale(10)
console.log(p2.x,p2.y)

  

类继承

和java一样,类继承有两种方式1 extend(继承父类) 2implements (实现接口)

定义子类的对象拥有父类和本类的方法

class Animal{
    move(){
        console.log('Moving along!')}
}

class Dog extends Animal {
    bark(){
        console.log('汪')
    }
}

const dog = new Dog()
dog.move()
dog.bark()

结果:

接口:和java差不多

interface Singable {
    sing():void
}

class Person1 implements Singable {
    sing(){
        console.log("明天开学")
    }
}

只读修饰符

readonly:表示只读,用来防止在构造函数之外对属性进行赋值。

只读的属性必须要设定默认值,并且readonly只能修饰属性不能修饰方法

接口或者{}表示的对象类型,也可以使用readonly

class Person2 { 

    readonly age:number =18
    constructor(age:number) {
        this.age = age
    }
}

 有readonly修饰的属性不能被其他的方法修改

 在使用readonly时最好手动指定属性类型,不然类型自动推断的类型可能不是我们想要的

接口或者{}表示的对象类型,也可以使用readonly

猜你喜欢

转载自blog.csdn.net/qq_53478650/article/details/128817601