typeScript总结 -- 基础(一)

125 阅读5分钟

简介

一、typeScript与JavaScript

简单来说,ts是JavaScript的超集。js的代码可以放在ts运行。

typeScript = JavaScript + type

--ts可以简单的理解为给Js加上了代码保护
--JavaScript边解释边运行,属于动态编程语言,只有在运行的时候才能发现错误。而ts 需要先编译再执行(编译成js)

二、安装环境

由于ts 不能被浏览器所接受,所以我们需要将ts 编译成js 再进行执行。

 npm i -g typescript
 tsc -v  //查看版本类型

新建一个hello.ts 文件,通过执行tsc hello编译成hello.js

基础

一、基础类型

语法变量名:[基本类型] = 赋值

简单类型

1 、boolean、number/string、null、undefined

let age:number = 12
let tips:string = "warning"
let timer : null = null
let unVar :undefined = undefined
let flag :boolean = true
let symbolVar : symbol = symbol()

在默认情况下 let age:number = null
let tips:string = undefined
不会报错


2 、 any 和 unknown
如果不确定是什么类型,可以使用any类型。
any类型不建议使用,这样就失去了类型检查的ts的意义

let  unVar :any = ""
unVar = 5
unVar = false

不建议使用any,但是当不确定值类型的时候可以选择unknown
unknown 类型 + 类型断言可以比较好的解决这个问题


3、never

never 表示永远不可能存在值的类型,任何值都不能赋给never类型

数组类型

//数组类型写法1
let numbersArr : number[] = [1,2,3]
//数组类型写法2
let strArr : Array<string> = ["delete","copy"]
//调用数组的方法
numbersArr.push(4)

元组类型

顾名思义,元素构成的数组。本质还是数组,所以可以使用数组的方法。是一种已知元素数量和类型的数组。

//元组类型

let tuple:[number,string,string] = [18,"cici",'']
tuple[2] = "hello"
console.log(tuple)

二、 函数

//普通函数

function addFn (num1:number ,num2 :number) : number {
    return num1 + num2
}

//箭头函数

const  sliceFn = (str:string,index:number):string => {
    return str[index]
}

1 、void
函数的返回值类型void,当函数没有return,或者returnundefined,或者只有return,没有具体的返回值。函数返回的类型选择 void


function sayHi ():void{
    console.log("helloworld")
}

如果return undefined 不能声明返回类型为undefined 会报错


2 、可选参数和默认值

// begin 带 ? 表示参数可选 ,end:number = 1 默认值为1// end:number = 1 同时也代表了end可选 ,这里不再需要?
const getStr = (str:string , begin?:number , end:number = 1) : string => {
    return str.slice(begin,end)
}

3 、 函数重载

写法并不常用,大概理解就是传入的参数的类型不同,会做出相对应的类型处理。需要多次声明

//函数重载

function handleFn(x:number,y:number):number
function handleFn(x:string,y:string):string
function handleFn(x:any,y:any):any{
    if(typeof x === "number"){
        return x+y
    }
    if(typeof x === "string"){
        return (x+y).toLocaleUpperCase()
    }
}
console.log(handleFn(1,2))
console.log(handleFn('abc','ef'))

三、Interface

1.用来定义对象类型

//定义user

interface User {
    name:string,
    age:number*,*
    //可选参数
    level?: number
    //只读参数
    readonly id :number
}
const p1:User = {
    name:"cici",
    age:18,
    id:1
}
p1.id = 3 //err
console.log(p1)

2.不确定对象属性

//不确定对象属性

interface randomObj{
    [propName:string]:string
}
interface randomObj2{
    [propName:number]:string
}
let obj1:randomObj = {
    "jazz":"jazzTT",
    "hiphop":"hiphopZZ"
}
let obj2:randomObj2 = ["a","b"]

这里的obj2其实是个伪数组,*伪数组的详细的可以参考我另一篇文章* ——伪数组的概念

四、类

1.基本写法
class关键字是从es6引入的,想要详细的了解了解我的另一篇文章--ES6
-在Ts 中,class的写法和js类似,只是增加了一些类型定义。
-通过 publicprivateprotected 三个修饰符来增强了 JS 中的类。

class User {
    name:string
    age:number
    constructor(name:string){
        this.name = name
    }
    showName():void{
        console.log(`my name is ${this.name}`)
    }
}
let user1 = new User("CICI")
console.log(user1.name)
user1.showName()

2.继承


class vipUser extends User {
    level:number
    constructor(name:string,level:number){
        super(name)
        this.level = level
    }
    showLevel():string{
        return this.level === 1?'高级':'低级'
    }
}
let u2 = new vipUser("cendi",2)
u2.showName()
console.log(`${u2.name}的vip等级${u2.showLevel()}`)

3.public/private/protected

  • public 公有属性,一个类里默认的方法和属性都是public
  • private 私有属性,只属于类本身,实例和子类都访问不到
  • protected 受保护的,只有它的子类可以访问到,实例访问不到
//class

class User {
     private age:number
     protected sex : boolean
    name:string
    constructor(name:string,age:number,sex:boolean){
        this.name = name
        this.age = age
        this.sex = sex
    }
    showName():void{
        console.log(`my name is ${this.name}`)
    }
    showAge(){
        console.log(`my age is ${this.age}`)
    }
    protected showPro(){
        console.log("this is a protected function")
    }
    private showAll(){
        console.log("this is a private function")
    }
    showPrivate(){
        this.showAll()
    }
}
let user1 = new User("CICI",18,true)
console.log(user1.name)
//console.log(user1.age)  报错 私有属性
//console.log(user1.sex)   报错 保护属性
user1.showAll()    //报错  私有方法
user1.showPrivate()   //通过公有方法访问私有变量
user1.showAge()
class vipUser extends User {
    level:number
    constructor(name:string,age:number,sex:boolean,level:number){
        super(name,age,sex)
        this.level = level
    }
    showLevel():string{
        return this.level === 1?'高级':'低级'
    }
    showSex(){
        console.log(`this is a ${this.sex ? 'girl' :'boy'}`)
    }
}
let u2 = new vipUser("cendi",20,true,2)
u2.showName()
u2.showSex()
//console.log(u2.sex)
console.log(`${u2.name}的vip等级${u2.showLevel()}`)

3、static
静态变量 无法外部访问

class circle {
    static PI:number = 3.14
    public radius:number
    constructor(radius:number){
        this.radius = radius
    }
    getMJ():number{
        return Math.pow(this.radius,2) * circle.PI ;
    }
}
let c1 = new circle(5)
c1.PI   //报错:无妨访问静态变量
c1.getMJ()

4.抽象类

  • 不能被实例化
  • 抽象类中的抽象方法必须被子类实现
  • 关键字abstract
//抽象类
abstract class Animals{
    name:string
    constructor(name:string){
        this.name = name
    }
    abstract say():void
}
class Dogs extends Animals{
    type:number
    constructor(name:string){
      super(name)
    }
    say(): void {          //抽象类的方法必须在子类中继承实现
        console.log("this is a dog")
    }
}
class cats extends Animals{
    type:number
    constructor(name:string){
      super(name)
    }
    say(): void {       //多态
        console.log("this is a cat")
    }
}
const a1 = new Animals("wangcai") //报错  不能实例化 抽象类

多态是面向对象的重大特征之一。其作用就是定一个抽象方法,在子类中进行不同的实现。

5.interface 和 class

  • 使用implements关键字来约束class的方法

//使用interface 来约束 class
 interface MovieModel{
      startPaly():void
      endPlay():void
      next():void
      prev():void
 }
   class txMovie implements MovieModel {
    startPaly():void{
       console.log("this is start function")
    }
    endPlay():void{
        console.log("this is stop function")
    }
    next():void{
        console.log("this is next function")
    }
    prev():void{
        console.log("this is prev function")
    }
   }

这样做的意义在于,规定一个interface来约定一个接口保证一个视频播放器需要以上的四个方法。使用这个接口来约束一个xxMovie必须拥有以上四个方法。

  • 约束构造函数静态属性
  interface cirxleStatic {
    PI:number
    new( raduis:number):void
  }
  const circle2:cirxleStatic = class circle2 {
    static PI:number = 3.14
    public radius:number
    constructor(radius:number){
        this.radius = radius
    }
    getMJ():number{
        return Math.pow(this.radius,2) * circle.PI ;
    }
}
let c2 = new circle2(5)
c1.getMJ()

五.枚举

在一个范围内有规律的常量,可以使用enum来定义

  • 默认从0 开始计数
  • 如果第一个值有赋值,则从第一个值开始累加
  • 可以反向映射
  • 可以手动赋值
// 枚举
enum weeks{
   Monday,Tuesday,Wednesday,Thursday
}
console.log(weeks.Monday)     0
console.log(weeks.Tuesday)    1
console.log(weeks.Wednesday)  2
console.log(weeks.Thursday)   3

// 枚举
enum weeks{
   Monday = 1,Tuesday,Wednesday,Thursday
}
console.log(weeks.Monday)     1
console.log(weeks.Tuesday)    2
console.log(weeks.Wednesday)  3
console.log(weeks.Thursday)   4

//反向映射
console.log(weeks[4])    thursday

//手动赋值
enum statusStart {
    start = 100,
    end = 200
}

使用const enum定义的常量枚举要比enum定义的枚举 编译出来的js代码简洁,提高了性能。

六.其他

1.类型推论
在ts中,没有明确的指出类型的地方,ts 会在初始化返回值时候帮助提供类型。

  • 定义时不赋值,就会被 TS 自动推导成 any 类型,之后随便怎么赋值都不会报错。
  • 定义时赋值,会根据赋值类型自动认定为该类型。
  • 函数的默认参数返回值进行推论

2.DateError /RegExp

let date:Date = new Date()
let err:Error = new Error("WARING")
let red:RegExp = /^abc/