typescript 基础

211 阅读5分钟

看了一下ts,感觉就是翻版java,我怀疑是后端为了卷前端造出来的,anyway,大概看了下基础,感觉对js 理解有帮助,同事说,万物皆接口

类型

// 布尔值
let flag:boolean=true

let a:number=123

let str:string = "xxx"

let arr:string[] = ['a', 'b']
let arr:Array<number> = [1,2,3]

// 元组
let arr:[string, number, boolean] = ['a', 1, false]

// 枚举 定义标识符
enum Flag {
    success = 1
    error = -1
}
var f:Flag = Flag.success

// any js 获取dom 元素,修改属性

// undfined null

方法

// void ts中没有任何类型,用于定义方法没有返回值
function run():void{
    console.log('run')
}

// never 其他类型(null,undefined)的子类型,从不会出现的值,

// function
function run():string{
    return 'run'
}

let fun2 = function():number{
    return 123
}

// ?表示可选参数
let fun = function(name:string, age?:number, grade:string='女'):string{
    return `${name}:${age}`
}

  • // 类 class Person { name:string constructor(n:string) { // 实例化类的时候触发的方法 this.name = n } run():void { alert(this.name) } } var p = new Person('zs') p.run()

  • 类继承

    //类继承 class Web extends Person{ constructor(name:string){ super(name) // 子类中执行父类的构造函数 } } var w = new web('ls') w.run()

  • 类修饰符

    // 类 修饰符: // public:公有, 类、子类、类外面都可以访问--默认公有 // protected:保护,类、子类里可访问,类外面不可访问 // private:私有,类里可访问,子类、类外都不可访问 class Person { protected name:string static sex:string = '女' constructor(n:string) { this.name = n } run():void { // 实例方法 alert(this.name) } static print() { // 静态方法,不能访问类属性,只能访问静态属性 console.log(this.name) // 报错 console.log(this.sex) // 🉑️ } }

  • 多态

    // 多态 父类定义方法不实现,让继承子类实现,每个子类都有不同的表现class zs extend Person{ constructor(n:string) { super(n) } run():void { // 重新实现的父类方法 alert('zs') } }

  • 抽象类

    // 抽象类,提供其他类继承的基类,不能直接被实例化 -- 定义标准 // absctract 定义的抽象类、抽象方法,不包含具体实现且必须在派生类中实现 // 抽象方法只能出现在抽象类中 abstract class Animal { name:string constructor(name:string) { this.name = name } abstract eat():any }

    // let d = new Animal() 🙅 抽象类不可以被实例化 class Dog extends Animal { constructor(name:any) { super(name) } eat(){ console.log(this.name + '吃粮食') } }

    let d = new Dog('hello') d.eat()

接口

接口是规范的定义,定义行为和动作规范

  • 属性接口

    // 属性接口

    interface FullName{ first:string; // 注意 ; 结束 second?:string; // 可选属性 }

    function printName(name:FullName) { console.log(name.first+name.second) }

    var obj={ age:20, first: 'zhang', second: '三' }

    printName(obj)

  • 函数类型接口

    // 函数类型接口:对方法传入的参数、返回值进行约束 //加密函数类型接口

    interface encrypt{ (key:string, value:string):string; }

    var md5:encrypt = function(key:string, value:string):string{ return key+value }

  • 可索引接口:数组、对象的约束,不常用

    interface UserArr { [index:number]:string }

    var arr:UserArr = ['a', 'b']

    interface UserObj { [index:string]:string } var arr:UserObj={name: 'zs'} //基本用不到,只有这一种情况

  • 类 类型接口:对类的约束,跟抽象类有点相似

    interface Animal { name: string; eat(str:string):void; }

    class Dog implements Animal{ name:string; constructor(name:string){ this.name = name } eat(){ console.log(this.name + '吃粮食') }

    }

  • 接口扩展,接口可以继承接口

    interface Animal{ eat():void; }

    interface Person extends Animal{ work():void; }

    class Web implements Person{ public name:string; constructor(name:string) { this.name = name } eat() { console.log(this.name + '吃杂粮') } work() { console.log(this.name+ '工作') } }

泛型

解决类、接口、方法的复用性,以及对不特定数据类型的支持。一个组件可以支持多种类型的数据,用户可以根据自己的数据类型来使用组件

function getData<T>(value:T):T{
    return 'hahha'
}

getData<number>(123)

// 泛型类
class MinClass<T>{
    public list:T[] = []
    
    add(num:T):void {
        this.list.push(num)
    }

    min():T{
        var minNum = this.list[0]
        for(var i=0; i<this.list.length; i++) {
            if(minNum > this.list[i]) {
                minNum = this.list[i]
            }
        }
        return minNum
    }
}

//泛型接口
interface ConfigFn{
    <T>(value:T):T;
}

var getData:ConfigFn = funciton<T>(value:T):T{
    retrun value
}

泛类:泛型可以避免重复的代码以及对不特定数据类型的支持(类型校验)

class User {
    username: string | undefined,
    password: string | undefined
}

//class MysqlDb {
    add(user:User):boollean{
        return true;
    }
//}

// 泛类,防止重复写
class MysqlDb<T> {
    add(info:T):boollean{
        return true;
    }
}
var u = new User()
u.username = 'zs'
u.password = '123'

var Db = new MysqlDb<User >()
Db.add(u)

模块:外部模块,用于代码服用,一个模块里由多个命名空间

命名空间:内部模块,用于组织代码、避免命名冲突

namespace A {}

装饰器:一个方法,可以扩展类、属性、方法、参数的功能

分类:类装饰器、属性装饰器、方法装饰器、参数装饰器

写法:普通装饰器(无法传参)、装饰器工厂(可传参)

执行顺序:

  • 属性>方法>方法参数>类
  • 若有多个同样的装饰器,先执行后面的

类装饰器

类声明之前声明,用于类构造函数,监视、修改、替换类定义

类的构造函数是类装饰器的唯一参数

function logClass(params:any) {
    console.log(params) // httpclient 类
    params.prototype.apiUrl = 'xxxx'
}
// 普通装饰器
@logClass
class HttpClient{
    constructor(){}
    getData(){}
}

var http = new HttpClient()

//装饰器工厂

function logClass(params:string) {
    return function(target:any) {
        console.log(target) // httpclient 类
        console.log(params)

        target.prototype.apiUrl = params
    }
}

@logClass('hello')
class HttpClient{
    constructor(){}

    getData(){}
}

属性装饰器

在运行的时当作函数被调用,传入下列2个参数

  1. 对于静态成员来说是类的构造函数,对于实例成员是原型对象

  2. 成员的名字

    function logProperty(params:any) { return function(target:any, attr:any) { console.log(target) console.log(attr) target[attr] = params } }

    class HttpClient{ @logProperty('xxxx') public url:any | undefined constructor() {} getData() { console.log(this.url) } }

方法装饰器

应用到方法的属性描述符上,可用来监视、修改,代替方法定义

function get(params:any) {
    return function(target:any, methodName:any, desc:any) {
        console.log(target)
        console.log(methodName)
        console.log(desc)
        console.log(desc.value) // 方法 
    }
}

class HttpClient{
    public url:any | undefined;
    constructor(){}
    @get('xxxx')
    getData(){
        console.log(this.url)
    }
}

方法参数装饰器

会在运行时当作函数被调用,可以使用参数装饰器为类的原型添加一些元素数据,传入下列3个参数

  1. 对静态成员来说是类的构造函数,对实力成员是类的原型对象

  2. 方法的名字

  3. 参数在函数参数列表中的索引

    function logParams(params:any) { retrun function(target:any, methodName:any,paramsIndex: any) { console.log(params) console.log(target) console.log(methodName) console.log(paramsIndex) } }

    class HttpClient{ public url: any | undefined; constructor(){} getData(@logParams('xxx') uuid:any) {

    }
    

    }

    var http:any = new HttpClient() http.getData(1234567)