• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

typescript学习笔记

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Tpyescript


typescitpt安装 编译

安装

npm install -g typescript
yarn global add typescipt

tsconfig.json配置文件

{
  "compilerOptions": {
    "module": "CommonJS",
    "outDir": "./dist",
    "target": "es5",
    "strictNullChecks": true,

    "watch": true
  },
  "include": [
    "./src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

执行命令

tsc

typescript中的数据类型

//布尔类型(boolean) true false
var flag:boolean=true;
//数字类型
var a:number=123;
console.log(a)
//字符串类型
var str:string="this is demo";
// str=111; 报错

// 数组类型(array)  ts中定义数组有两种方式

//1.第一种定义数组方式
// let arr:number[]=[1,2,3,4,\'122\']; 报错,数组元素必须全是数字
let arr:string[]=[\'php\',\'.net\',\'go\']; //字符串数组

//2.第二种定义数组的方式
let arr1:Array<number>=[1,2,3,4,5];
console.log(arr1);

//元祖类型 tuple  属于数组的一种
let arr2:[string,number,boolean]=[\'ts\',3.12,true];

//枚举类型,事先考虑到某一变量可能取得值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法。用这种方法定义的类型称为枚举类型
/*
* enum 枚举名{
*   标识符[=整型常数],
*   标识符[=整型常数],
*   ....
*   标识符[=整型常数],
* };
*  //举例; pay_status  0 未支付   1支付  2 交易成功
* */
enum Flag{
    success=1,
    error=-1
}
var f:Flag=Flag.success;
console.log(f);//1

//任意类型 (any) 可以是任意类型。
var num:any="122";
num="str";
//任意类型的用法 可以用来解决获取dom节点的时候ts报错。
// var oBox:any=document.getElementById(\'box\');
// oBox.style.color=\'red\';

//null和undefined  其他数据类型的子类型
//定义没有赋值就是undefined
var num1:number | undefined;
console.log(num1);
var num2:null;
num2=null;
//元素可能是number类型,也可能是null,可能是undefined
var num3:number | null | undefined;
num3=1222;
console.log(num3)

//void类型   typescript 中的void表示没有任何类型 一般用于定义方法的时候方法没有返回值
function run():void {
    console.log(\'run\');
}
run();
//never类型,是其他类型(包括null和undefined)的子类型,代表从不会出现的值。这意为着never的变量只有被never类型所赋值。

typescript中的函数

/*
* ts中的函数用法
* */
//函数中声明法
function run1():string{
    return \'1222\'
}

//匿名函数
var fun2=function():number{
    return 11;
}
console.log(fun2()); //调用方法

//ts中定义传参
function getInfo(name:string,age:number):string{
    return `${name}---${age}`
}
console.log(getInfo(\'zhangsan\',20));

//没有返回值的方法
function run2():void{
    console.log(\'1111\');
}
run2();

//方法可选参数 要使用?  注意可选参数必须配置到参数的最后面
function getInfo1(name:string,age?:number):string{
    if(age){
        return `${name}---${age}`
    }else{
        return `${name}---年龄保密`
    }
}
console.log(getInfo1(\'张三\'));
console.log(getInfo1(\'张三\',122));

//默认参数
function getInfo2(name:string,age:number=20):string{
    if(age){
        return `${name}---${age}`
    }else{
        return `${name}---年龄保密`
    }
}
console.log(getInfo2(\'张三\'));
console.log(getInfo2(\'张三\',122));

//剩余参数
//三点运算符   接收新参数传过来的值
function sum(...result:number[]):number{
    let sum=0;
    for(var i=0;i<result.length;i++){
        sum+=result[i]
    }
    return  sum;
}
console.log(sum(1,3,7)); //11

//第二种写法
function sum1(a:number,b:number,...result:number[]):number{
    let sum=a+b;
    for(var i=0;i<result.length;i++){
        sum+=result[i]
    }
    return  sum;
}
console.log(sum1(1,3,7,333)); //344

//函数重载
/* 重载指的是两个或者两个以上同名函数,但他们的参数不一样,这时会出现函数重载的情况*/
/*  typescript中的重载,通过为统一函数提供多个函数类型定义来尝试下多种功能的目的*/

function getInfo3(name:string):string;
function getInfo3(age:number):string;
function getInfo3(str:any):any{
    if(typeof str===\'string\'){
        //字符串类型
        return \'我叫:\'+str
    }else{
        //数字类型
        return \'我的年龄是:\'+str
    }
}
console.log(getInfo3(\'张三\')); //正确
console.log(getInfo3(1222)); //正确
// console.log(getInfo3(true));  报错
function getInfo4(name:string):string;
function getInfo4(name:string,age:number):string;
function getInfo4(name:any,age?:any):any{
    if(age){

        return \'我叫:\'+name+\'年龄是\'+age
    }else{

        return \'我叫:\'+name
    }
}
console.log(getInfo4(\'张三\')); //正确 我叫:张三
console.log(getInfo4(\'猪头\',111)); //正确  我叫:猪头年龄是111

//箭头函数  es6  箭头函数里面的this指向上下文
setTimeout(()=>{
    console.log(\'run\')
},1000)

typescript中的类

/*ts中的类*/
//es5里面的类
//1. 最简单的类
function Person(){
    this.name=\'战三\';
    this.age=20;
}
//实例化
var p=new Person();
console.log(p.name); //战三
//2. 构造函数和原型链里面增加方法
function Person1(name,age){
    this.name=name;
    this.age=age;
    //run是实例方法,必须通过new完一个实例,才能调用
    this.run=function(){
        console.log(this.name+\'在运动\')
    }
}
//类的静态方法
// Person1.getInfo=function(){
//     console.log(\'我是静态方法\')
// }
//在原型链添加属性和方法
//原型链上面的属性会被多个实例共享, 构造函数不会
Person1.prototype.sex="男";
Person1.prototype.work=function(){
    console.log(this.name+\'在工作\');
}
//es5的继承
//web类继承Person类  原型链+对象冒充的组合继承模式

function web(name,age) {
   Person1.call(this,name,age); //对象冒充实现继承
}
web.prototype=Person1.prototype;
var w=new web(\'张三dd\',12);
w.run();  //对象冒充可以继承构造函数里面的属性和方法。
// w.work(); // 报错   对象冒充无法继承原型链上的属性和方法。
w.work(); //原型链继承可以实现
var w=new web(\'ddddd\',122);
w.run();  //对象冒充可以继承构造函数里面的属性和方法。
// w.work(); // 报错   对象冒充无法继承原型链上的属性和方法。
w.work(); //原型链继承可以实现
// var p1=new Person1();
// p1.run(); //战三在运动
// p1.work(); //战三在工作
//调用静态方法
// Person1.getInfo();//我是静态方法


/* ts中的类的写法*/
class Person5{
    name:string; //属性,前面省略了public关键字
    constructor(name:string) {//构造函数
        this.name=name;
    }
    run():void{
        console.log(this.name+"在跑路");
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
let p1=new Person5(\'张三\');
p1.run();//张三在跑路
console.log(p1.getName());// 获取name属性
p1.setName(\'kay\');//设置name属性
console.log(p1.getName());// 重新获取name


ts的类的继承

/* ts中的类的写法*/
class Person5{
    name:string; //属性,前面省略了public关键字
    constructor(name:string) {//构造函数
        this.name=name;
    }
    run():void{
        console.log(this.name+"在跑路");
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
//继承
class web5 extends Person5{
    constructor(name:string) {
        //super表示调用的父类构造函数,内部的this指向子类的的
        //super指向父类的原型对象,所以定义在父类实例上的方法或属性是无法通过super调用的。
        super(name);//初始化父类的构造函数
    }
}
let p1=new Person5(\'张三\');
p1.run();//张三在跑路
console.log(p1.getName());// 获取name属性
p1.setName(\'kay\');//设置name属性
console.log(p1.getName());// 重新获取name

ts的类的继承方法重写

/* ts中的类的写法*/
class Person5{
    name:string; //属性,前面省略了public关键字
    constructor(name:string) {//构造函数
        this.name=name;
    }
    run():void{
        console.log(this.name+"在跑路");
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
//继承 方法的重写
class web5 extends Person5{
    constructor(name:string) {
        //super表示调用的父类构造函数,内部的this指向子类的的
        //super指向父类的原型对象,所以定义在父类实例上的方法或属性是无法通过super调用的。
        super(name);//初始化父类的构造函数
    }
    run():string{
        return `${this.name}在运动`
    }
    work():string{
        return `${this.name}在工作`
    }
}



let w5=new web5(\'李四\');
console.log(w5.work());
console.log(w5.run());
// let p1=new Person5(\'张三\');
// p1.run();//张三在跑路
// console.log(p1.getName());// 获取name属性
// p1.setName(\'kay\');//设置name属性
// console.log(p1.getName());// 重新获取name


类的修饰符

/* ts中的类的写法*/
/*
* 修饰符
* public 公有  在类里面。子类  类外面都能访问
* protected 保护类型  在类里面,子类里面可以访问,在类外无法访问
* private  私有   在类里面可以访问  子类  类外部都没法访问.
* 属性不加修饰符,默认是public
* */
class Person5{
    public name:string; //属性,前面省略了public关键字
    constructor(name:string) {//构造函数
        this.name=name;
    }
    run():void{
        console.log(this.name+"在跑路");
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
//继承 方法的重写
class web5 extends Person5{
    constructor(name:string) {
        //super表示调用的父类构造函数,内部的this指向子类的的
        //super指向父类的原型对象,所以定义在父类实例上的方法或属性是无法通过super调用的。
        super(name);//初始化父类的构造函数
    }
    run():string{
        return `${this.name}在运动`
    }
    work():string{
        return `${this.name}在工作`
    }
}
let p5=new Person5(\'ddd\');
//类外部访问
console.log(p5.name);//ddd


let w5=new web5(\'李四\');
console.log(w5.work());
console.log(w5.run());



类的静态属性 ,静态方法

/* ts中的类的写法*/
/*
* 修饰符
* public 公有  在类里面。子类  类外面都能访问
* protected 保护类型  在类里面,子类里面可以访问,在类外无法访问
* private  私有   在类里面可以访问  子类  类外部都没法访问.
* 属性不加修饰符,默认是public
* */
class Person5{
    public name:string; //属性,前面省略了public关键字
    constructor(name:string) {//构造函数
        this.name=name;
    }
    run():void{
        console.log(this.name+"在跑路");
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
//继承 方法的重写
class web5 extends Person5{
    public good:number=1222;
    //定义一个静态属性
    static timer:string=\'111\';

    constructor(name:string) {
        //super表示调用的父类构造函数,内部的this指向子类的的
        //super指向父类的原型对象,所以定义在父类实例上的方法或属性是无法通过super调用的。
        super(name);//初始化父类的构造函数
    }
    run():string{
        return `${this.name}在运动`
    }
    work():string{
        return `${this.name}在工作`
    }
    //定义一个静态方法  静态方法,里面没法之间调用类里面的属性 只能调用静态属性
    static  go():void{
        // console.log(this.good);
        console.log(this.timer);
    }
}
let p5=new Person5(\'ddd\');
//类外部访问
console.log(p5.name);//ddd


let w5=new web5(\'李四\');
console.log(w5.work());
console.log(w5.run());
//调用静态方法
web5.go();//\'111\'



抽象 类和 多态

/*多态:父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表示*/
/*多态属于继承*/
class Animal{
    name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat():void{
        console.log(\'吃的方法\');
    }
}
//子类
class Dog extends Animal{
    constructor(name:string) {
        super(name);//初始化父类的构造函数
    }
    eat():string{
        return this.name+\'吃肉\';
    }
}
class Cat extends  Animal{
    constructor(name:string) {
        super(name);
    }
    eat():string{
        return this.name+\'吃老鼠\';
    }
}

/*
* typesctipt中的抽象类,他是提供其他类继承的基类,不能被实例化
* 用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体事项并且必须在派生类中事项。
* abstract抽象方法只能放在抽象类里面
* 抽象类和抽象方法用来定义标准,标准: Animal这个类要求它的子类必须包含eat方法
* */
abstract  class Animal{
    public name:string;
    constructor(name:string) {
        this.name=name;
    }
    abstract eat():any;
}

class Dog extends Animal {
    //抽象类的子类必须实现抽象类的里面的抽象方法
    constructor(name:any) {
        super(name);
    }
    eat(){
        console.log(this.name+\'吃鱼头\');
    }
}
var d=new Dog(\'王公子\');
d.eat()

typescript中的接口

接口的作用,在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一类所需要遵守的规范。接口不关心这些类的内部状态数据。也不关心这些类的方法的实现细节,它只规定了这批类里必须提供某些方法,提供这些方法的类可以满足实际需要。typescript中的接口类似于java.同时还增加了更灵活的接口类型,包括属性,函数,可索引和类等。

属性接口

/**接口**/
//属性接口 对json的约束
//对批量方法传入参数进行约束
//接口:行为和动作的规范,对批量方法进行约束
interface FullName {
    firstName:string; //注意;结束
    secondName:string;
}
function printName(name:FullName) {
    //必须传入对象 firstName secondName
    console.log(name.firstName+\'---\'+name.secondName);
}
var obj={
    age:20,
    firstName:\'张\',
    secondName:\'三\'
}
printName(obj)//张---三

//接口 可选属性
interface FullName {
    firstName:string;
    secondName?:string;
}
function getName(name:FullName){
    console.log(name)
}
getName({
    firstName:\'firstName\'
})

例子: ts封装ajax

interface Config {
   type:string;
   url:string;
   data?:string;
   dataType:string;

}
function ajax(config){
    var 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\'){
                JSON.parse(xhr.responseText)
            }else{
                console.log(xhr.responseText);
            }
        }
    }
}
ajax({
    type:\'get\',
    url:\'http://www.baidu.com\',
    dataType:\'json\'
})

函数类型接口

/*
函数类接口: 对方方传入的参数,以及返回值进行约束
*/
//加密的函数类型接口
interface encrypt {
    (key:string,value:string):string;
}
var md5:encrypt=function (key:string,value:string):string {
    //模拟操作
    return key+value;
}
console.log(md5(\'name\',\'zhangsan\'));

var sha1:encrypt=function(key:string,value:string):string{
    return key+\'---\'+value;
}

可索引接口

/*
可索引接口 数组 对象的约束(不常用)

*/
//索引是number 对数组的约束
interface userArr {
    [index:number]:string
}
var arr9:userArr=[\'aaa\',\'bbbb\'];
//可索引接口 对对象的约束
interface UserObj {
    [index:string]:string
}
var obj9:UserObj={name:\'张三\',\'data\':\'111\'};

类类型接口

/*类类型接口:对类的约束 和抽象类有点相似*/

interface Animal10 {
    name:string;
    eat10(str:string):void;

}
class Dog10 implements  Animal10{
    name:string;
    constructor(name:string) {
        this.name=name;

    }
    eat10(){
        console.log(this.name+\'吃猪头\');
    }
}
var d10=new Dog10(\'小黑\');
d10.eat10();//小黑吃猪头

class Cat10 implements  Animal10{
    name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat10(food:string) {
        console.log(this.name+food)
    }
}
var c10=new Cat10(\'小花\');
c10.eat10(\'猪头\');

接口的扩展、接口的继承

//接口扩展,接口可以继承接口
interface  Animal11 {
    eat11(): void;
}
interface Person11 extends Animal11{
    work11():void;
}
class Web11 implements Person11{
    public  name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat11(){
        console.log(this.name+\'喜欢吃馒头\');
    }
    work11(){
        console.log(this.name+\'写代码\');
    }
}
var w11=new Web11(\'小李\');
w11.work11();//小李写代码


//接口扩展,接口可以继承接口
interface  Animal11 {
    eat11(): void;
}
interface Person11 extends Animal11{
    work11():void;
}
//
class coder{
    public name:string;
    constructor(name:string) {
        this.name=name;
    }
    coding(code:string){
        console.log(this.name+code);
    }
}
//web11继承 coder类 ,同时继承了Person11接口
class Web11 extends coder implements Person11{

    constructor(name:string) {
        super(name);
    }
    eat11(){
        console.log(this.name+\'喜欢吃馒头\');
    }
    work11(){
        console.log(this.name+\'写代码\');
    }
}
var w11=new Web11(\'小李\');
w11.work11();//小李写代码
w11.coding(\'写ts代码\');//小李写ts代码




typescript中的泛型

泛型: 软件工程中,我们不仅要创建一致的定义良好的api,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持维拉的数据类型,这在创建大型系统时为提供了十分灵活的功能. 通俗理解: 泛型: 就是解决接口方法的复用性,以继对不特定数据类型的支持。

泛型类

/*泛型 可以支持不特定的数据类型  要求,传入的参数和返回的参数一致*/

//T 表示泛型 ,具体什么类型是调用这个方法的时候决定的。
function getData<T>(value:T):T{
    return value;

}
//调用时输入类型
console.log(getData<number>(123)); //123
console.log(getData<string>(\'gogogo\')); //gogogo
/*泛型 可以支持不特定的数据类型  要求,传入的参数和返回的参数一致*/

//T 表示泛型 ,具体什么类型是调用这个方法的时候决定的。
// function getData<T>(value:T):T{
//     return value;
//
// }
// //调用时输入类型
// console.log(getData<number>(123)); //123
// console.log(getData<string>(\'gogogo\')); //gogogo

//泛型类,比如有个最小堆算法,需要同时支持返回数字和字符串两种类型,通过类的泛型来实现。
class MinClass<T>{
    public  list:T[]=[];
    add(value:T):void{
        this.list.push(value);
    }
    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;
    }
}
var m1=new MinClass<number>(); /*实例化类,并且制定了类的类型是number*/
m1.add(2);
m1.add(7);
m1.add(444);
console.log(m1.min()); //输出最小是2
var m2=new MinClass<string>(); /*实例化类,并且制定了类的类型是string*/
m2.add(\'a\');
m2.add(\'g\');
m2.add(\'v\');
console.log(m2.min()); //输出最小是\'a\'

泛型函数接口

/*泛型函数接口*/
// 第一种写法
interface ConfigFn {
    <T>(value:T):T;
}
var  getData:ConfigFn=function<T>(value:T):T{
    return value;
}
console.log(getData<string>(\'张三\'));// 张三
console.log(getData<number>(1111)); //1111

//第二种写法
interface ConfigFn<T>{
    (value:T):T;
}
function getData<T>(value:T):T{
    return value;
}
//选择string类型
var myGetData:ConfigFn<string>=getData;
//调用
console.log(myGetData(\'20\'));//\'20\'

泛型类实例Db类

/*
* 定义一个user的类的这个类的作用就是映射数据库字段
* 然后定义一个MysqlDb的类这个类用于操作数据库
* 然后把User类作为参数传入到MysqlDb中
* */
//把类作为参数来约束数据传入类型
class User{
    username:string |undefined;
    password: string| undefined;
}
class MysqlDb{
    add(user:User):boolean{
        console.log(user);
        return true;
    }
}
var u=new User();
u.username=\'张三\';
u.password=\'12233\';

var Db=new MysqlDb();
Db.add(u);
/*
* 定义一个user的类的这个类的作用就是映射数据库字段
* 然后定义一个MysqlDb的类这个类用于操作数据库
* 然后把User类作为参数传入到MysqlDb中
* */
//把类作为参数来约束数据传入类型
// class User{
//     username:string |undefined;
//     password: string| undefined;
// }
// class MysqlDb{
//     add(user:User):boolean{
//         console.log(user);
//         return true;
//     }
// }
// var u=new User();
// u.username=\'张三\';
// u.password=\'12233\';
//
// var Db=new MysqlDb();
// Db.add(u);

//操作数据库的泛型类
class MysqlDb<T>{
    //增添操作
    add(info:T):boolean{
        console.log(info);
        return true;
    }
    //更新操作
    updated(info:T,id:number):boolean{
        console.log(info);
        console.log(id);
        return true;
    }
}
//想给User表增加数据
//1.定义一个User类  和数据库进行映射
class User{
    username:string | undefined;
    password: string | undefined;
}

var u=new User();
u.username=\'钩子\';
u.password=\'1111\';
var Db1=new MysqlDb<User>();
console.log(Db1.add(u));//User { username: \'钩子\', password: \'1111\' } true

//定义文章类
class ArticleCate{
    title: string | undefined;
    desc:string | undefined;
    status: number | undefined;
    constructor(params:{
        title: string | undefined;
        desc:string | undefined;
        status?: number | undefined;
    }) {
        this.title=params.title;
        this.desc=params.desc;
        this.status=params.status;
    }
}
//实例化文章类
var a1=new ArticleCate({
    title:\'分类\',
    desc:\'1111\'
});
//实例化数据库类 类型检测ArticleCate
var Db2=new MysqlDb<ArticleCate>();
//添加操作
console.log(Db2.add(a1));//ArticleCate { title: \'分类\', desc: \'1111\', status: undefined } true
//更新操作
var a2=new ArticleCate({
    title:\'分类dddd\',
    desc:\'222\'
});
a2.status=1;
var Db3=new MysqlDb<ArticleCate>();
console.log(Db3.updated(a2,12));//ArticleCate { title: \'分类dddd\', desc: \'222\', status: 1 } 12 true


/*
综合应用
ts封装统一操作 mysql Monggodb  Mssql的底层库
功能: 定义一个操作数据库的库,支持mysql Mssql  MongoDb
要求: mysql msSql mongoDb功能一样 都有 add update  delete get方法
注意: 约束统一的规范,以及代码重用
解决方案: 需要越苏规范所以要定义接口,需要代码重用所以用到泛型
1.接口: 在面向对象的编程中,接口是一种规范的定义,它定义行为和动作的规范。
2.泛型: 通俗理解: 泛型就是解决类接口方法的复用性。
*/
interface  DBI<T> {
    add(info:T):boolean;
    update(info:T,id:number):boolean;
    delete(id:number):boolean;
    get(id:number):any[];
}
//定义一个操作mysql数据库的类  注意:要实现泛型接口  这个类也应该是一个泛型类
class MysqlDb<T> implements DBI<T>{
    constructor() {
        console.log(\'数据库建立连接\');
    }
    add(info: T): boolean {
        console.log(info);
        return true;
    }

    delete(id: number): boolean {
        return false;
    }

    get(id: number): any[] {
        return [];
    }

    update(info: T, id: number): boolean {
        return false;
    }

}
//定义一个操作mssql数据库的类
class MssqlDb<T> implements DBI<T>{
    add(info: T): boolean {
        console.log(info);
        return true;
    }

    delete(id: number): boolean {
        return true;
    }

    get(id: number): any[] {
        var list=[
            {
                title:\'1111\',
                desc:\'xxx\'
            },
            {
                title:\'12221\',
                desc:\'dmmmdld\'
            },
        ]
        return list;
    }

    update(info: T, id: number): boolean {
        return false;
    }

}

//操作用户表  定义一个User类和数据表的映射
class User{
    username:string | undefined;
    password: string | undefined;
}
var u=new User();
u.username=\'ddd\';
u.password=\'12344\';
var oMssql=new MssqlDb<User>();
oMssql.add(u); //User { username: \'ddd\', password: \'12344\' }
var data=oMssql.get(2);
console.log(data)//[ { title: \'1111\', desc: \'xxx\' },{ title: \'12221\', desc: \'dmmmdld\' } ]





typescript模块

模块的概念(自己理解): 我们可以把一些公共的功能单独抽离成一个文件作为一个模块。模块里面的变量函数类等默认是私有的,如果我们要在外部访问模块里面的数据(变量 函数 类),我们需要通过export暴露模块里面的数据
(变量 函数 类)。暴露后我们通过import引入模块可以使用模块里面暴露的数据(变量 函数 类)

//db.ts
//第一种暴露方式
export var dbUrl=\'xxxxx\';
export function getData(){
    console.log(\'获取数据库的数据\')
    return [
        {
            title:\'111122\'
        },
        {
            title:\'122ddddd\'
        }
    ]
}
export function save() {
    console.log(\'保存数据成功\');
}
//index.ts中接收
import {getData,save} from \'../modules/db\'
//export default getData; //default只能调用一次
getData();//获取数据库的数据
save();//保存数据成功
//第二种方式
 var dbUrl=\'xxxxx\';
function getData(){
console.log(\'获取数据库的数据\')
return [
    {
        title:\'111122\'
    },
    {
        title:\'122ddddd\'
    }
]
}
function save() {
console.log(\'保存数据成功\');
}
export {dbUrl,getData,save};
//index.ts中接收
import {getData,save} from \'../modules/db\'

getData();//获取数据库的数据
save();//保存数据成功

//接收default
import getData from \'./modules/db\'
getData();

封装类似Mongoose风格的类库


db.ts

interface  DBI<T> {
    add(info:T):boolean;
    update(info:T,id:number):boolean;
    delete(id:number):boolean;
    get(id:number):any[];
}
//定义一个操作mysql数据库的类  注意:要实现泛型接口  这个类也应该是一个泛型类
export class MysqlDb<T> implements DBI<T>{
    constructor() {
        console.log(\'数据库建立连接\');
    }
    add(info: T): boolean {
        console.log(info);
        return true;
    }

    delete(id: number): boolean {
        return false;
    }

    get(id: number): any[] {
        return [];
    }

    update(info: T, id: number): boolean {
        return false;
    }

}
//定义一个操作mssql数据库的类
export class MssqlDb<T> implements DBI<T>{
    add(info: T): boolean {
        console.log(info);
        return true;
    }

    delete(id: number): boolean {
        return true;
    }

    get(id: number): any[] {
        var list=[
            {
                title:\'1111\',
                desc:\'xxx\'
            },
            {
                title:\'12221\',
                desc:\'dmmmdld\'
            },
        ]
        return list;
    }

    update(info: T, id: number): boolean {
        return false;
    }

}

Article.ts

import {MssqlDb} from "../modules/db";

class ArticleClass{
    title:string | undefined;
    desc: string | undefined;
}
var ArticleModel=new MssqlDb<ArticleClass>();
export {
    ArticleClass,ArticleModel
}

User.ts

import {MssqlDb} from "../modules/db";

//操作用户表  定义一个User类和数据表的映射
class UserClass{
    username:string | undefined;
    password: string | undefined;
}
var UserModel=new MssqlDb<UserClass>();
export {
    UserClass,UserModel
}
// u.username=\'ddd\';
// u.password=\'12344\';
// var oMssql=new MssqlDb<UserClass>();
// oMssql.add(u); //User { username: \'ddd\', password: \'12344\' }
// var data=oMssql.get(2);
// console.log(data)//[ { title: \'1111\', desc: \'xxx\' },{ title: \'12221\', desc: \'dmmmdld\' } ]

index.js

import {UserClass,UserModel} from "../model/user";

//增加数据
var u=new UserClass();
u.username=\'张三\';
u.password=\'112222\';
UserModel.add(u);

//获取user表数据
var res=UserModel.get(122);
console.log(res);

import {ArticleModel,ArticleClass} from "../model/article";

//获取文章的数据
var aRes=ArticleModel.get(1);
console.log(aRes);

typescript命名空间

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似的功能的函数、类、接口等放置到命名空间内。

  • 命名空间: 内部模块,主要用于组织代码,避免命名冲突
  • 模块:ts的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。



//命名空间  作用域的方法和变量是私有的,需要export才能导出使用
//a.ts  存放命名空间
export namespace A{
    interface Animal {
        name:string;
        eat():void;
    }
    export class Dog implements  Animal{
        name:string;
        constructor(theName:string) {
            this.name=theName

        }
        eat(){
            console.log(`${this.name}吃狗粮`)
        }
    }
    export class Cat implements  Animal{
        name:string;
        constructor(theName:string) {
            this.name=theName;
        }
        eat(){
            console.log(`${this.name}吃猫粮`)
        }
    }
}
export namespace B{
    interface Animal {
        name:string;
        eat():void;
    }
    export class Dog implements  Animal{
        name:string;
        constructor(theName:string) {
            this.name=theName

        }
        eat(){
            console.log(`${this.name}吃狗粮`)
        }
    }
    export class Cat implements  Animal{
        name:string;
        constructor(theName:string) {
            this.name=theName;
        }
        eat(){
            console.log(`${this.name}吃猫粮`)
        }
    }
}
// console.log(1111);
//1.ts
//导入命名空间A,B
import {A,B} from \'../modules/a\'
//命名空间外部使用 A的类
var d=new A.Dog(\'大黄\');
d.eat();//大黄吃狗粮
//命名空间外部使用B的类
var c=new B.Cat(\'喵喵折\');
c.eat();//喵喵折吃猫粮


demo结果



typescript装饰器

装饰器: 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或者参数上,可以修改类的行为。

通俗来讲: 装饰器就是一个方法,可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能。

常见的装饰器有: 类装饰器,属性装饰器,方法装饰器,参数装饰器

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

类装饰器

类装饰器: 类装饰器在类声明之前被声明(紧靠着声明) 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义,并传入一个参数。

/* 类装饰器*/
function logClass(params:any) {
    //params就是当前类
    console.log(params)// [Function: HttpClient]
    params.prototype.apiUrl=\'动态扩展属性\';
    //扩展动态方法
    params.prototype.run=function(){
        console.log(\'我是一个run方法\');
    }

}
//调用装饰器用@ 普通装饰器无法传参
@logClass
class HttpClient{
    constructor() {
    }
    getData(){

    }
}
var http:any=new HttpClient();
console.log(http.apiUrl);//动态扩展属性
http.run();//我是一个run方法
/* 类装饰器*/
/*
* 1.2类装饰器,装饰器工厂(可传参)
* */
function logClass(params:string) {
    return function(target:any){
        console.log(target);//把类 传参给
        // console.log(params); //www.baidu.com
        target.prototype.apiUrl=params;

    }

}
//调用装饰器用@
@logClass(\'www.baidu.com\')
class HttpClient{
    constructor() {
    }
    getData(){

    }
}
var http:any=new HttpClient();
console.log(http.apiUrl); //www.baidu.com



/*
类装饰器
* 重载构造函数的例子
类构造器表达式会在运行时当做函数被调用,类的沟站函数作为其唯一的参数。
如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
* */
function logClass(target:any){
    console.log(target);
    return class extends target{
        apiUrl:any=\'我是修改后的数据\';
        getData(){
            this.apiUrl=this.apiUrl+\'----\';
            console.log(this.apiUrl);
        }
    }
}

@logClass
class HttpClient{
    public apiUrl:string | undefined;
    constructor() {
        this.apiUrl=\'我是构造函数里面的apiUrl\'
    }
    getData(){
        console.log(this.apiUrl);
    }
}
var http=new HttpClient();
http.getData();//我是修改后的数据----

属性装饰器

属性装饰器表达式会在运行时,当做函数被调用,传入下列两个参数

  • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
  • 成员的名字
/*
类装饰器
* 重载构造函数的例子
类构造器表达式会在运行时当做函数被调用,类的沟站函数作为其唯一的参数。
如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
* */
//视频时间 20.06
//类装饰器
function logClass(params:string){
   return function (target:any) {
        // console.log(target);
        // console.log(params);
   }
}
//属性装饰器
function logProperty(params:any){
    return function(target:any,attr:any){
        console.log(target) //HttpClient { getData: [Function] }
        console.log(attr) //apiUrl
        target[attr]=params;
    }
}
@logClass(\'xxxxx\')
class HttpClient{
    @logProperty(\'xxxsssss\')
    public apiUrl:string | undefined;
    constructor() {

    }
    getData(){
        console.log(this.apiUrl)//xxxsssss
    }
}
var http=new HttpClient();
http.getData();//我是修改后的数据----

方法装饰器

他会应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。

/*
方法装饰器  它会接应应用到方法的属性的描述符上,可以用来监视,修改或者替换方法的定义
方法的装饰会在运行时传入下列3个参数
1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
2.成员的名字
3.成员的属性描述符
*/
//方法装饰器
function logMethod(params:any){
    return function (target:any,methodName:any,desc:any) {
        console.log(target); //HttpClient { getData: [Function] }
        console.log(methodName); //getData
        console.log(desc); // { value: [Function],writable: true, enumerable: true,configurable: true }
        target.apiUrl=\'mssmmsmsm\';
        target.run=function () {
            console.log(\'run\')
        }



}
}
class HttpClient{
    public  url:any | undefined;
    constructor() {

    }
    @logMethod(\'xxxx\')
    getData(){
        console.log(this.url);
    }
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();


//方法装饰器  修改getData方法
function logMethod(params: any) {
    console.log(params)
    return function (target: any, methodName: any, desc: any) {
        console.log(target); //HttpClient { getData: [Function] }
        console.log(methodName); //getData
        console.log(desc.value); //方法定义
        //修改装饰器的方法,把装饰器方法里面传入的所有参赛改为string类型
        //保存当前的方法
        var oMethods=desc.value;
        //替换
        desc.value=function (...args:any[]) {
            args=args.map((value)=>{
                return String(value)
            })
            console.log(args);
            //修改方法 对象冒充
            oMethods.apply(this,args);

        }

    }
}

class HttpClient {
    public url: any | undefined;

    constructor() {

    }

    @logMethod(\'xxxx\')
    getData(...args:any[]) {
        console.log(args)
        console.log(\'我是getData中的方法\');
    }
}

var http: any = new HttpClient();

http.getData(\'123\',\'xxx\');//[ \'123\', \'xxx\' ]



方法参数装饰器

参数装饰器表达式会在运行时当做函数直接调用,可以使用参数装饰器为类的原型增加一些元素数据,传入下列3个参数

  • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • 参数的名字
  • 参数在函数参数列表的索引。

//方法参数
function logParams(params:any) {

    return function (target: any, methodName: any, paramsIndex: any) {
        console.log(params)
        console.log(target);
        console.log(methodName);
        console.log(paramsIndex);
        target.apiUrl=params;
    }
}

class HttpClient {
    public url: any | undefined;

    constructor() {

    }

    getData(@logParams(\'uuiddddddddd\') uuid: any) {
        console.log(\'我是getData里面的方法\')
        console.log(uuid+\'----\');
    }
}

//实例化
var http:any = new HttpClient();
http.getData(11111)
console.log(http.apiUrl);


装饰器的执行顺序

属性>方法>方法参数>类 如果有多个同样的装饰器,它会优先执行后面的(从里到外的执行顺序)


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
使用Typescript重构axios(三十)——添加axios.getUri方法发布时间:2022-07-18
下一篇:
typescript学习记录-联合类型(14)发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap