TS的重新学习

前言

最近项目中引入了TS,打算深入学习一下TS

typescript是js的超集,它可以编译成纯js,ts可以在任何浏览器和操作系统上运行,并且是开源的。

1、安装

全局进行安装:npm install -g typescript

2、查看是否安装成功

在cmd中输入命令 tsc -v 查看是否下载成功,输入命令出现版本号则下载成功

TS类型

ts支持与js几乎相同的数据类型,此外还提供了枚举类型,ts支持的类型包括:布尔、数字,字符串、数组、枚举、any、never、null、undefined、object、void、类型断言

  • TS出现是弥补js的类型缺失
  • TS代码要运行在浏览器中,需要进行类型转换,转换为js代码
  • TS类型包含所有JS类型null、undefined、string、number、boolean、symbol
  • 还包含void、never、enum、unkonow、any以及ts自定义的type和interface

变量声明

var/let/const 标识符:数据类型 = 赋值

const data: string = 'hello

const userName: string

userName = '小王子的玫瑰花'

userName = 10

如果没有明确指定类型,TS会隐式推出一个类型,这类型根据赋值自动类型推断,没有赋值则为any类型。

const data2: any

let data2

基础类型

// string 字符串类型,可以使用单引号、双引号、反引号表示

const a: string = 'hello'

// number 数字类型,同样支持进制表示,但也不区分整数和浮点数

const b: number = 10

// boolean 布尔类型只有两个值:true 和false

const c: boolean = true

// undefiend null 既是实际的值,也是类型

const n: null = null

const u: undefiend = undefiend

// bigInt

const bInt: bigint = 10n

// Symbol

const s1 = Symbol('s1')

const s2 = Symbol('s2')

const info = {
   [s1]: '张三',
   [s2]: '李四'
}

数组和元组

// Array<元素类型> 这种写法可能存在与jsx 冲突问题

const arr1: Array<number> = [1, 2, 3]

// 元素类型后面接上[],表示由此类型元素类型组成的一个数组

const arr2: number[] = [1, 2, 3]

// 数组里面可能有字符串和数字

const arr3: (number | string)[] = [1, 2, '小王子的玫瑰花']

// 元组已知元素数量和类型的数组,元组一定要指明类型

const tuple: [string, number] = ['张三', 18]

对象类型 

  • TS中的对象类型泛指所有的非原始类型,比如:对象、数组、函数
  • 使用object定义一个新对象,但是这个对象不能设置新数据也不能修改来数据
const obj: Object = {
  name : '测试'
}

obj.age = 20

obj.name = '王麻子'

如下所例所限制对象类型更为精确,可限制每个属性的类型

const p1: { name: string; age: number } = { name: '王小二', age: 18 }

const p2:  {name: string; age?: number } = { name: '云母' }

any、unknown、never

  • 无法确定一个变量的类型,可使用 any,此时在其身上做任何操作都是合法的,即使访问了一个不存在的属性
  • 如果某些情况处理类型过于繁琐,或者在引入一些第三方库时,缺失了类型注解,这个时候 我们可以使用 any,更多是为了兼容老代码
  • unknown 类型表示一个值可以是任何类型,它是所有类型的父类型,任何类型都可以赋值给 unknown 类型,但是 unknown 类型只能赋值给 any 类型和 unknown 类型本身
  • 类似 any,与 any 类型不同的是,unknown 类型的变量不能直接赋值给其他类型的变量,也不能调用其上的任何方法或属性,除非先进行类型检查或类型断言,这样确保运行时的类型安全
  • 默认在其操作都是不合法的,主要是在编写通用代码时,例如编写库或框架时,需要处理来自不同来源的数据,但又不确定数据的类型
  • never 类型表示这种永不存在值的类型
  • 它是一个底层类型,不是任何类型的子类型,也没有任何子类型

函数类型

  • 声明函数时,可以在每个参数后添加类型注解,声明其参数类型
  • 同样也可以声明返回值的类型,不过也可以不写让 TS 自动推导
  • 函数参数的一般顺序 必传参数 - 有默认值的参数 - 可选参数
// nl 接受 number 类型的参数,同样返回number 类型

function fn1(n1: number): number{
 
  return n1 

}

// 箭头函数写法

const fn2:(n1:number)=>number=n1=>{

    return n1

}

// n1的默认值是10,n2 是可选类型参数,...args 是剩余参数,代表接受一个只读的number类型数组

// 返回值是 void 代表可以返回 undefined 或者不return

const fn3 =(n1:number=10,n2?: number,...args:readonly number[]):void =>{

  return undefined
  
}

枚举类型

  • 枚举类型将一组可能出现的值,一个个列举,定义在一个类型中,这个类型就是枚举

这种字符串的枚举可能使用 type Direction = 'LEFT' | 'RIGHT' | 'TOP' | 'RIGHT'可能会更好点

type Direction = 'LEFT' | 'RIGHT' | 'TOP' | 'BOTTOM'

function turnDirection(direction: Direction) {}

turnDirection('LEFT')

interface 和 type

  • 使用 interface 定义接口,使用 type 定义类型别名
  • 都可以约束对象的结构

区别

  1. interface 只描述对象,type 则可以描述所有数据
  2. interface 使用 extends 来实现继承,type 使用 & 来实现交叉类型
  3. interface 会创建新的类型名,type 只是创建类型别名,并没有创建新类型
  4. interface 可以重复声明扩展,type 则不行(别名是不能重复的)
// 方式一:使用interface

interface IPoint {
  X: number,

  readonly y: number,
  
  z?: number
}

// 方式二:使用type

type Poin {
  x: number,
  
  y: number
}

类型、非空、常量断言

  • 类型断言 as,当 TS 无法获取到具体的类型信息,就需要使用类型断言(Type Assertions)
  • 它可以允许我们断言成更具体或者不太具体的(比如any)的类型
const arr = [110, 120, 119, 112]

const res = arr.find(i => i > 0)

const num1=res as number // 断言res 是number

const num2=<number>res // 或者这种方式。JSX下不能使用

// 这种获取元素方式 TS 只知道该函数会返回HTMLImageElement不知道具体类型

const el= document.getElementById('img')as HTMLImageElement

el.src ='url地址'
  • 非空类型断言 !,当我们确定参数有值,需要跳过 TS 对它的检测的时候可以使用
function fn(msg?: string) {

  console.log(msg!.length)

}
  • 常量断言 as const,将类型尽量收窄到字面量类型,如果用在对象后面,相当于给对象里面每个成员加上 readonly

const arr = [1, 'hello'] as const

const obj: {

 readonly a: 1,
 
 readonly b: 2

}

const obj = {

   a: 1,

   b: 2

} as const

基本类型和普通对象

// 简单类型兼容

type StringOrNumber = string number

const msg:String0rNumber = 'hello' // 较小的类型可以赋值给较大的类型

// 普通对象兼容

interface Person {

    name: string,

    age: number

}

let user = {

    name: '测试',

    age: 18,

    id: 1

}

const p:Person=user // 属性多的可以赋值给属性少的

function printPerson(p: Person) {}

printPerson(p)

printPerson({

    name: 'zhangsan',
    
    age: 18,

    id: 1
})

  • ES6 之前使用函数实现类,ES6可以使用 class 关键字声明一个类
  • 在默认的 strictPropertyInitialization 模式下面我们的属性是必须在constructor 初始化的,如果没有初始化,那么编译时就会报错,如希望此模式下不报错,可以使用 name!: string 的语法
  • 类拥有自己的构造器 constructor ,当我们通过 new 关键字创建一个实例时会被调用,类中定义的函数叫方法

1、基本使用

class Person {

  name: string,
 
  age: number


constructor(name:string, age:number) {
  this.name = name

  this.age = age

}

eating(){

 console.log(this.name +'eating')

 }

}

const p = new Person('测试',18)

console.log(p.name,p.age)// 测试 18

p。eathing()

2、类的继承:使用 extends 关键字来实现继承,子类中使用 super 来访问父类

class Student {
    
    gender: string
    
    constructor(name: string, age: number, gender: string) {

        // super调用父类的构造器
        
        super(name, age)

        this.gender = gender
    }

    // 重写

    eathing() {

        console.log('student eating')

        // 内部调用父类的 eating 方法

        super.eating()

    }

    studying() {
    
        console.log('studying')

    }
}


const stu = new Student('王小二',18,'男')

console.log(stu.name, stu.age, stu.genter)

stu.eathing() // student eathing 王小二eathing

3、类的成员修饰符

  • 在 TS 中,类的属性和方法支持三种修饰符: publicprivateprotected
  • public:类外可见,默认编写的属性就是 public 的
  • protected:类和子类中可见
  • private:仅自身类可见
  • #属性:实现私有属性,并且类型擦除之后还有效
class Person {

    private name: string = ''

    protected age:number = 0

    constructor(name: string,age: number){ 

      this.name = name

      this.age = age
    
    }
   // 封装了两个方法,外部只有通过方法来访问和设置内部私有属性name

    getName() {

        return this.name

    }

    setName(newName: string) {

        this.name = newName

    }
}

class Student extends Person {

    // 构造器 private 就不能使用 new Student 创建实例

    private constructor(name: string,age: number) {

        super(name, age)

    }

    getAge() {

        return this.age

    }

    static create(name: string,age: number){

        return new Student(name, age)

    }
}

泛型

  • 定义函数的时候不决定参数的类型
  • 而是让调用者使用尖括号形式传入对应函数
  1. 比如我们实现一个函数,传入一个参数并返回它,保证这个参数和返回值类型一致
function fn<Type>(args: Type): Type {
  
  return args

}

2、传入多个类型

function fn<T,E>(n1:T,n2:E) {}

其中,T,E 这些都是我们可以自定义的,它们代表的意义是

  • T(Type):类型
  • K(key)、V(value):,键值对
  • E(Element):元素
  • O(Object):对象

内置类型声明

  • TS 帮我们内置了一些运行时标准化 API 的声明文件
  • 比如 FunctionStringMathDateRegExpError 等内置类型
  • 也包含运行环境中的 DOM 、BOM API,比如 WindowDocumentHTMLElementEventNodeList
  • const b: Boolean = new Boolean(true)
    
    const n: Number = new Number(true)
    
    const s:String = new String('云牧牧')
    
    const d: Date = new Date()
    
    const r:RegExp =编辑/^hello/
    
    const e: Error =new Error('err')

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值