typescript基础学习笔记

117 阅读5分钟

==心得:对前端开发者来说,TS能强化了「面向接口编程」这一理念。我们知道稍微复杂一点的程序都离不开不同模块间的配合,不同模块的功能理应是更为清晰的,TS能帮我们梳理清不同的接口。,TS能让我更自信的写前端代码,这种自信来自 TS的类型检测可以帮我们避免很多可能由于自己的忽略造成的 bug==

一、基本数据类型


1、布尔类型: let flag:boolean = false flag = true 2、数字类型 let num:number num = 10 3、字符串类型 let str:string str = 'this is strType' 4、数组类型 let arr:any[] = []//any类型指任何类型,数组里面既可以放数字类型也可以放字符串 let arrNum:number[]//只能在数组里面存放数字类型 let arrString:string[]//只能在数字里面存放字符串类型 其他方式定义数组 let arrNum:Array<number> = [1,3,5] let arrStr:Array<string> = ['a','b','c'] 5、元组类型 let arr:[string,number,boolean] = ['str',100,true] 6、枚举类型 enum 枚举名{ 标识符[=整型常数] 标识符[=整型常数] 标识符[=整型常数] ... } 定义一个flag枚举类型,1表示成功,-1表示失败

`enum Flag{
    success = 1
    error = -1
}`

let f:Flag = Flag.success 7、任意类型 let anyType:any 指定为空类型 let number : null | number void类型,一般用于方法,表示没有返回任何类型

function funVoid():void{
    console.log('没有返回值')
}//void返回类型
function funNumber():number{
    return 100
}//定义返回number

二、函数的定义


1、函数声明法

function fun1():string{
    console.log('no return')
}
function fun2():number{
    return 100
}
function fun3():string{
    return 'string'
}

2、匿名函数

const fun1 = function():void{
    console.log('no return')
}
const fun2 = function():number{
    return 100
}
const fun3 = function():string{
    return 'string'
}

3、typescript定义方法传参

const getInfo = function(name:string,age:number):string{
    return `${name}---${age}`
}

箭头函数

const getInfo = function(name:string,age:number):string=>{
    return `${name}---${age}`
}

可选参数:在变量后加一个?,表示这个参数可传可不传

const getInfo = function(name:sting,age?:number):void=>{
    
}

默认参数

const getInfo = function(name:string,age:number=18):void=>{
    
}

剩余参数

const surplus = (a:number,b:number,c?:number):number=>{
    return a+b+c
}
surplus(1,2) //输出3

定义一个数组来接收参数

const sum = (...res:number[])=>{
    let sum = 0
    res.map(item =>{
        sum +=item
    })
    return sum
}
sum(1,2,3) //打印处和为6

三、typescript中的类和继承


1、类的定义

class Person{
    name:string //属性
    //构造器,实例化类的时候会触发的方法
    constructor(name:string){
        this.name = name
    }
    //定义一个set和get的方法
    getName():string{
        return this.name
    }
    setName(name:string):void{
        this.name = name
    }
    //定义一个人物动作的方法
    run():string{
        return `${this.name}在跑步`
    }
}
<!--实例化一个人类-->
const p = new Person('张三')//传入张三,因为定义了构造器,所以这里必传
p.run()//打印出张三在跑步
p.setName('李四')//调用setname方法,传入李四
p.run()打印出李四在运动

2、类的继承 extends和super

<!--定义一个中国人继承上面的人类-->
class ChineseMan extends Person{
    constructor(name:string){
        super(name)
    }
    work():string{
        return `${this.name}在工作`
    }
}
const cm = new ChineseMan('王五')
cm.work()//打印王五在工作
cm.run()//打印王五在跑步

3、类的修饰符 public:在子类,类内部和外部都可以调用 private:只能在类内部调用 protected:不能在类外部调用*

<!--定义一个动物类-->
class Animal{
    public name:string
    public age:number = 20
    //静态属性
    public static color:string = '黑色'
    //构造器
    constructor(name:string){
        this.name = name
    }
    //静态方法
    static run(name:string){
        console.log(this.color)//这里可以获取到值,因为定义的是一个静态属性
        console.log(this.age)//反之这里拿不到age的值,因为静态方法不能直接调用类里面已声明值的属性
        return `${name}在跑步`
    }
}
<!--调用静态方法-->
Animal.run('李四')//打印处李四在跑步

4、多态 父类定义一个方法不去实现,让继承他的子类去实现,每一个子类有不同的表现

//定义一个动物类
class Animal{
    public name:string
    constructor(name:string){
        this.name = name
    }
    //定义一个吃的方法
    eat():void{
        
    }
}
//定义一个小狗去继承动物类
class Dog extends Animal{
    constructor(name:string){
       super(name)
    }
    eat(){
        return `${this.name}吃骨头`
    }
}
//定义一个小猫去继承动物类
class Cat extends Animal{
    constructor(name:string){
       super(name)
    }
    eat(){
        return `${this.name}吃鱼干`
    }
}
实例化类
const dog = new Dog('小狗')
dog.eat()//小狗吃骨头
const cat = new Cat('小猫')
cat.eat()//小猫吃鱼干

5、抽象类 1、提供其他类继承的基础,不能被直接实例化 2、用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现 3、抽象方法只能放在抽象类中

//定义一个抽象类
abstract class Animal{
    publi name:string
    constructor(name:string){
        this.name = name
    }
    //定义一个抽象方法,子类必须实现
    abstract eat():any
    //普通方法,子类可以不用实现
    run():any
}

const animal = new Animal()//会报错,因为无法创建抽象类的实例
<!--定义一个小狗类去继承animal-->

class Dog extends Animal{
      constructor(name:string){
        super(name)
    }
    //实现父类的抽象方法(必须实现,不然会报错)
    eat(){
        return `${this.name}吃骨头`
    }
    run(){
        return `${this.name}跑步,在子类可以不定义`
    }
}
const dog = new Dog('狗子')
dog.eat()//狗子在吃骨头
dog.run()//狗子在跑步,在子类可以不定义

四、typescript的接口


接口的作用,在面向对象编程中,接口是一种规范定义,他定义了行为和动作的规范,起到了一种限制和规范。 接口定义了某一批类所需要遵守的规范,接口不必关心这些类的内部状态数据,也不关心类里面实现的细节,只规定了这批类里必须提供某些方法,提供这些方法可以满足实际需要。

//定义一个接口
interface FullName{
    firstName:string
    secondName:string
}
//方法实现接口
function fullName(name:FullName):string{
    return `${name.firstName}----${name.secondName}`
    
}
const data = {
    otherParams:9//可以添加其他参数
    firstName:'张'
    secondName:'三'
}
fullName(data) //张-----三

1、封装一个ajax接口

$ajax({
    type:'get',
    url:'https://baidu.com',
    data:{username:$("#username").val(),content:$("#content").val()},
    datatype:'json'
})

//定义一个接口
interface ajax{
    type:string,
    url:string,
    data:any,
    datatype:string
}
//定义一个方法继承接口
function ajax(config:ajax):any{
    const xhr = new XMLHttpRequest
    xhr.open(config.type,config.url,true)
    xhr.send(config.data)
        xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            // console.log('请求成功')
            if (config.datatype == 'json') {
                // console.log(JSON.parse(xhr.responseText))
            }
        }

    }
}
//调用方法
const data = {
    type:'get',
    url:'baicu.com',
    data:'name=zhangsan',
    datatype:'json'
}
ajax(data)

2、函数型接口 对方法传入的参数以及返回值进行约束

//定义一个加密型函数接口
interface encrapt{
    //约束以下这个函数
    (key:number,value:number):number
}
//实现这个函数接口
const md5:encrapt = function (key:number,value:number):number{
    return key+value
}
const sha1:encrapt = function (key:number,value:number):number{
    return key+value
}
//调用
sha1(10,20) //30
md5(20,30) //50

3、类类型接口 对类的约束,和抽象类有点相似

//定义动物类接口
interface Animal{
   name:string,
   eat(str:string):void
}
//实现接口
class DogImp implements Animal{
    name:string
     constructor(name: string) {
         this.name = name
     }
     eat():void{
         console.log(`${this.name}在吃东西`)
     }
}
//实例化类
const di = new DogImp('小狗')
di.eat()//小狗在吃东西

class CatImp implements Animal{
    name:string
     constructor(name: string) {
         this.name = name
     }
     eat(str:string):void{
         console.log(`${this.name}${str}`)
     }
}
const ci = new CatImp('小猫')
ci.eat('吃鱼干')//小猫在吃鱼干

4、接口的拓展:接口可以继承接口

//动物类接口
interface Animal{
    eat():void
}

//人类接口 继承动物类接口
interface Person implements Animal{
    name:string
    constructor(name:string){
        this.name = name
    }
    //工作方法
    work():void{
        console.log(`${this.name}在工作`)
    }
    //吃的方法
    eat():void{
        console.log(`${this.name}在吃饭`)
    }
}
//实例化类
const person = new person('张三')
person.work()//张三在工作
person.eat()//张三在吃饭

四、typescript中的泛型


解决类,接口方法的复用性,以及不特定数据的支持性

现有个方法需要同时返回number和string类型
写法一:写两个方法,造成了代码的冗余
function fun1(num:number):number{
    return num
}
function fun2(str:string):string{
    return str
}
写法2:定义any类型,但是放弃了类型检查,比如传入number类型,就比如返回number类型,传入string类型就必须返回string类型
function fun(str:any):any{
    return str
}
写法3:泛型,T表示具体什么类型,是由调用这个方法的时候决定的
function fun<T>(str:T):T{
    return T
}
//调用
fun<number>(100)//这里定义了number类型,就只能传入number
fun<string>('str')//这里定义了字符串类型,就只能传入字符串

2、泛型类

求最小值
class MinNum{
    public list:number[]
    addd(num:number):void{
        this.list.push(num)
    }
    min():number{
        let min = this.list[0]
        this.list.map(item =>{
            if(item < min){
                min = item
            }
        })
        return item
    }
}
const mn = new MinNum()
mn.add(1)
mn.add(2)
mn.min()//输出1

用泛型,定义一个泛型类
class MinNum<T>{
    publi list:T[]
    add(num:T):void{
        this.list.push(num)
    }
    min():T{
        let min = this.list[0]
        this.list.map(item =>{
            if(item < min){
                min = item
            }
        })
        return min
    }
}
const mn = new MinNum<number>()//实例化类,并定义类型
mn.add(1)
mn.add(2)
mn.min()//输出1

3、泛型接口 普通接口

interface configFun{
    (val1:string,val2:string):string
}
const interFun:configFun = function(val1:string,val2:string){
    return val1+val2
}
interFun('晚上','吃饭')

泛型接口

interface configFun<T>{
    (val:T):T
}
const interFun :configFun<T>(val:T):T{
    return val
}
interFun<string>('嘻嘻哈哈')
interFun<number>(100)