【总结】VUE3 中 TypeScript 的相关知识点

173 阅读11分钟

一、ts中的类型

1、typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验,在typescript中主要给我们提供了以下数据类型

布尔类型(boolean) 数字类型(number) 字符串类型(string) null 和 undefined

数组类型(array) 元组类型(tuple) 枚举类型(enum)

任意类型(any) void类型 never类型

1.1 语句写法
1.1.1 string/字符串 number/数值 boolean/布尔
let count:number	//可马上赋值可不赋值
let str:string = '112'
let flag:boolean = true
let num:number = 12
1.1.2 array 数组 的三种声明方式.
let arr1:number[] = [1,2,3]			//所有项为number
let arr2:Array<number> = [4,5,6]	//所有项为number
let arr4:any[] = ['1123', 23] 		//每一项为任意类型
1.1.3 array 数组 的三种声明方式
//可以给每个位置指定一种数据类型
let arr3:[number,string] = [12, '123']
1.1.4 tuple 元组(array的一种)
//可以给每个位置指定一种数据类型
let arr3:[number,string] = [12, '123']
1.1.5 enum 枚举
//相当于为数值命名,防止搞错
enum Flag {suc = 1, err = 2}
let f:Flag = Flag.err	//这里需要注意下 f:Flag
console.log(f)  //打印出2

enum Color {red, blue = 2, 'orange' }	//可加引号可不加
let c:Color = Color.red
console.log(c)  //打印出1,未赋值默认用下标 从1开始
let d:Color = Color.orange
console.log(d); //3
1.1.6 any 任意数据类型
let six:any = 'string'
	six = true
	six = document.getElementById('id')
1.1.7 void
//函数没有返回值的时候用 void 有返回值的时候用具体的数据类型
function run():void {
    console.log(11);
}
1.1.8 never 其他类型(代表从不会出现的值)
let a:never
// a=null 报错
a = (()=>{	//正确
    throw new Error('错误')
})()

二、ts 中类型使用

var num:number;
console.log(num)  //输出:undefined   报错

var num:number|undefined;
console.log(num)  //输出:undefined  //正确

//一个变量可能是 number类型 可能是null 可能是undefined
var num:number | undefined | null;
函数返回数据类型的定义
//错误写法
function run():undefined{
    console.log('run')
}
run();

//正确写法
function run():void{
    console.log('run')
}
run();

//正确写法
function run():number{
    return 123;
 }
 run();

// never类型:是其他类型 (包括 null 和 undefined)的子类型,代表从不会出现的值。
//这意味着声明never的变量只能被never类型所赋值。
var b:never;
b = (()=>{
    throw new Error("错误")
})()

const add: ()=>never = () => {
    while(true){ }
}

const fn: ()=>never = () => {
    throw new Error('error')
}

三、TS中函数的使用

1、函数的定义

ES5 中定义函数的方法

//函数声明法
function run(){
    return 'run';
}

//匿名函数
var run2=function(){
    return 'run2';
}

TS 中定义函数的方法

//命名函数声明法
function run():string{
  return 'run';
}

//命名错误写法
function run():string{
 return 123;
}

//匿名函数
var fun2=function():number{
  return 123;
}
alert(fun2()); /*调用方法*/

2、TS中定义方法传参

2.1 函数普通传参
function getInfo(name:string,age:number):string{
    return `${name} --- ${age}`;
}
alert(getInfo('zhangsan',20));

var getInfo=function(name:string,age:number):string{
    return `${name} --- ${age}`;
}
alert(getInfo('zhangsan',40));

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

//

2.2方法可选参数

ES5 里面方法的实参和行参可以不一样,但是ts中必须一样,如果不一样就需要配置可选参数

function getInfo(name:string,age?:number):string{
    if(age){
    	return `${name} --- ${age}`;
    }else{
    	return `${name} ---年龄保密`;
    }
}

alert(getInfo('zhangsan'))
alert(getInfo('zhangsan',123))

注意:可选参数必须配置到参数的最后面

2.3 默认参数 可选参数

ES5 里面没法设置默认参数,ES6和TS中都可以设置默认参数

 function getInfo(name:string,age:number=20):string{
     if(age){
         return `${name} --- ${age}`;
     }else{
         return `${name} ---年龄保密`;
     }
 }

alert( getInfo('张三'));
alert( getInfo('张三',30));
2.4 剩余参数

三点运算符 接受新参传过来的值, 否则TS不接受非形参的实参

function sum(...result:number[]):number{
    var sum=0;
    for(var i=0;i<result.length;i++){
        sum+=result[i];
    }
    return sum;
}
alert(sum(1,2,3,4,5,6)) ;

function sum(a:number,b:number,...result:number[]):number{
    var sum=a+b;
    for(var i=0;i<result.length;i++){
        sum+=result[i];
    }
    return sum;
}
alert(sum(1,2,3,4,5,6)) ;

3、 TS函数重载

  • java中方法的重载:重载指的是两个或者两个以上同名函数,但它们的参数不一样,这时会出现函数重载的情况。
  • typescript中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
  • ts为了兼容es5 以及 es6 重载的写法和java中有区别。
ES5中的重载
//es5中出现同名方法,下面的会替换上面的方法

function css(config){}
function css(config,value){}
TS中的重载(1)
 function getInfo(name:string):string;
 function getInfo(age:number):string;
 function getInfo(str:any):any{
     if(typeof str==='string'){
         return '我叫:'+str;
     }else{
         return '我的年龄是'+str;
     }
 }

 alert(getInfo('张三'));   //正确
 alert(getInfo(20));   //正确
 alert(getInfo(true));    //错误写法
TS中的重载(2)
function getInfo(name:string):string;
function getInfo(name:string,age:number):string;
function getInfo(name:any,age?:any):any{
    if(age){
        return '我叫:'+name+'我的年龄是'+age;
    }else{
        return '我叫:'+name;
    }
}

alert(getInfo('zhangsan'));  /*正确*/
alert(getInfo(123));  错误
alert(getInfo('zhangsan',20));

4、箭头函数

不说了

四、ES5中的类和继承

1、ES5中的类

1.1 最简单的类

function Person(){
    this.name='张三';
    this.age=20;
}
var p=new Person();
alert(p.name);

1.2 构造函数和原型链里的属性和方法

function Person(){
    this.name='张三';  /*属性*/
    this.age=20;
    this.run=function(){
        alert(this.name+'在运动');
    }
}

//原型链上面的属性会被多个实例共享   构造函数不会
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}
var p=new Person();
alert(p.name);
p.run();
p.work();

1.3 类里面的静态方法

function Person(){
    this.name='张三';  /*属性*/
    this.age=20;
    this.run=function(){  /*实例方法*/
        alert(this.name+'在运动');
    }
}
Person.getInfo=function(){
    alert('我是静态方法');
}
//原型链上面的属性会被多个实例共享   构造函数不会
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

var p=new Person();
p.work();
//调用静态方法
Person.getInfo();

2、ES5中的继承

2.1 对象冒充实现继承

function Person(){
     this.name='张三';  /*属性*/
     this.age=20;
     this.run=function(){  /*实例方法*/
         alert(this.name+'在运动');
     }
}
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

//Web类 继承Person类   原型链+对象冒充的组合继承模式
function Web(){
    Person.call(this);    /*对象冒充实现继承*/
}

var w=new Web();
w.run();  //对象冒充可以继承构造函数里面的属性和方法
w.work();  //对象冒充可以继承构造函数里面的属性和方法   但是没法继承原型链上面的属性和方法

2.2 原型链实现继承

function Person(){
    this.name='张三';  /*属性*/
    this.age=20;
    this.run=function(){  /*实例方法*/
    	alert(this.name+'在运动');
    }
}
Person.prototype.sex="男";
Person.prototype.work=function(){
	alert(this.name+'在工作');
}

//Web类 继承Person类   原型链+对象冒充的组合继承模式
function Web(){}
Web.prototype=new Person();   //原型链实现继承

var w=new Web();
//原型链实现继承:可以继承构造函数里面的属性和方法 也可以继承原型链上面的属性和方法
w.run();
w.work();
2.2.1 原型链实现继承的 问题?
function Person(name,age){
    this.name=name;  /*属性*/
    this.age=age;
    this.run=function(){  /*实例方法*/
        alert(this.name+'在运动');
    }
}
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

function Web(name,age){}
Web.prototype=new Person();

var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
w.run();

2.3 原型链+对象冒充的组合继承模式

function Person(name,age){
    this.name=name;  /*属性*/
    this.age=age;
    this.run=function(){  /*实例方法*/
        alert(this.name+'在运动');
    }
}
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

function Web(name,age){
    Person.call(this,name,age);   //对象冒充继承   实例化子类可以给父类传参
}
Web.prototype=new Person();

var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
w.run();
w.work();

2.4 原型链+对象冒充继承的另一种方式

function Person(name,age){
    this.name=name;  /*属性*/
    this.age=age;
    this.run=function(){  /*实例方法*/
        alert(this.name+'在运动');
    }
}
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

function Web(name,age){
    Person.call(this,name,age);   //对象冒充继承  可以继承构造函数里面的属性和方法、实例化子类可以给父类传参
}
Web.prototype=Person.prototype;

var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
w.run();
w.work();

五、TS中的对象(类)和继承

1、TS 里面类的定义

1.1 一个简单的类

 class Person{
     name:string;   //属性  前面省略了public关键词

     constructor(n:string){  //构造函数   实例化类的时候触发的方法
         this.name=n;
     }

     run():void{
         alert(this.name);
     }
}

var p=new Person('张三');
p.run()

1.2、属性设置和获取

class Person{
    name:string;

    constructor(name:string){  //构造函数   实例化类的时候触发的方法
        this.name=name;
    }

    getName():string{
        return this.name;
    }

    setName(name:string):void{
        this.name=name;
    }
}

var p=new Person('张三');

alert(p.getName());
p.setName('李四');
alert(p.getName());

2、ts中实现继承 extends、 super

class Person{

    name:string;

    constructor(name:string){
        this.name=name;
    }

    run():string{
        return `${this.name}在运动`
    }
}
// var p=new Person('王五');
// alert(p.run())

class Web extends Person{
    constructor(name:string){
        super(name);  /*初始化父类的构造函数*/
    }
}

var w=new Web('李四');
alert(w.run());

2.1 ts中继承的探讨 父类的方法和子类的方法一致

 class Person{
     name:string;

     constructor(name:string){
         this.name=name;
     }

     run():string{
         return `${this.name}在运动`
     }
 }

 class Web extends Person{
     constructor(name:string){
         super(name);  /*初始化父类的构造函数*/
     }

     run():string{
         return `${this.name}在运动-子类`
     }

     work(){
         alert(`${this.name}在工作`)
     }
 }

var w=new Web('李四');
alert(w.run());
w.work();

3、类里面的修饰符 typescript里面定义属性的时候给我们提供了 三种修饰符

public :公有 在当前类里面、 子类 、类外面都可以访问 protected:保护类型 在当前类里面、子类里面可以访问 ,在类外部没法访问 private :私有 在当前类里面可以访问,子类、类外部都没法访问

属性如果不加修饰符 默认就是 公有 (public)

六、类中的静态属性和方法,抽象类及多态

1、静态属性 静态方法

1.1 ES5中的静态类和方法

function Person(){
    this.run1=function(){
    }
}
Person.name='哈哈哈';
Person.run2=function(){  //静态方法
}

var p=new Person();
Person.run2(); 静态方法的调用
1.1.2 看到这里可以思考一下在曾经使用的JQ$('#box').css('color','red')$.get('url',function(){ }) 的内部实现
function $(element){
    return new Base(element)
}

$.get=function(){}

function Base(element){
    this.element=获取dom节点;
    this.css=function(arr,value){
        this.element.style.arr=value;
    }
}

// $('#box').css('color','red')
// $.get('url',function(){ })

1.2 TS中静态属性和方法

class Per{
    public name:string;
    public age:number=20;
    //静态属性
    static sex:string ="男";
    constructor(name:string) {
            this.name=name;
    }
    run(){  /*实例方法*/
        alert(`${this.name}在运动`)
    }
    work(){
        alert(`${this.name}在工作`)
    }
    static print(){  /*静态方法  里面没法直接调用类里面的属性*/
        alert('print方法'+Per.sex);
    }
}
// var p=new Per('张三');
// p.run();

Per.print();
alert(Per.sex);

2、抽象类 多态

父类定义一个方法不去实现,让继承它的子类去实现 每一个子类有不同的表现 。

多态属于继承

class Animal {
    name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat(){   //具体吃什么  不知道   ,  具体吃什么?继承它的子类去实现 ,每一个子类的表现不一样
        console.log('吃的方法')
    }
}

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+'吃老鼠'
    }
}

2.1 抽象类、抽象方法

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

    abstract eat():any;

    run(){}
}

class Dog extends Animal{
    eat(){
        console.log('吃骨头')
    }
}

七、typeScript中的接口

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

定义标准。

1、属性类接口 (对json的约束)

1.1 对普通方法进行参数约束
// ts中定义方法
function printLabel():void {
    console.log('printLabel');
}
printLabel();

// ts中定义方法传入参数(调用此方法不传入字符串类型的参数就会报错)
function printLabel(label:string):void {
    console.log('printLabel');
}
printLabel('hahah');

// ts中自定义方法传入参数,对json进行约束 (此处不传入包含字符串类型的`label`属性的对象就会报错)
function printLabel(labelInfo:{label:string}):void {
    console.log('printLabel');
}
printLabel('hahah'); //错误写法
printLabel({name:'张三'});  //错误的写法
printLabel({label:'张三'});  //正确的写法

1.2 对批量方法传入参数进行约束。
接口:行为和动作的规范,对批量方法进行约束
// 就是传入对象的约束    属性接口
interface FullName{
    firstName:string;   //注意;结束
    secondName:string;
}

function printName(name:FullName){
    // 必须传入对象  firstName  secondName
    console.log(name.firstName+'--'+name.secondName);
}

 // printName('1213');  //错误
 var obj={   /*传入的参数必须包含 firstName  secondName*/
     age:20,
     firstName:'张',
     secondName:'三'
 };
 printName(obj)
接口:行为和动作的规范,对批量方法进行约束

interface FullName{
    firstName:string;   //注意;结束
    secondName:string;
}

function printName(name:FullName){
    // 必须传入对象  firstName  secondName
    console.log(name.firstName+'--'+name.secondName);
}

function printInfo(info:FullName){

    // 必须传入对象  firstName  secondName
    console.log(info.firstName+info.secondName);
}

var obj={   /*传入的参数必须包含 firstName  secondName*/
    age:20,
    firstName:'张',
    secondName:'三'
};
printName(obj);

printInfo({
    firstName:'李',
    secondName:'四'
})
接口 :可选属性
interface FullName{
    firstName:string;
    secondName:string;
}

function getName(name:FullName){
    console.log(name)
}
//参数的顺序可以不一样
getName({
    secondName:'secondName',
    firstName:'firstName'
})

interface FullName{
    firstName:string;
    secondName?:string;
}

function getName(name:FullName){

    console.log(name)
}
getName({
    firstName:'firstName'
})
1.3、接口实战(实现ajax)
interface Config{
    type:string;
    url:string;
    data?:string;
    dataType:string;
}

//原生js封装的ajax
function ajax(config: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('chengong');
           if(config.dataType=='json'){
               console.log(JSON.parse(xhr.responseText));
           }else{
               console.log(xhr.responseText)
           }
       }
   }
}

ajax({
    type:'get',
    data:'name=zhangsan',
    url:'http://a.itying.com/api/productlist', //api
    dataType:'json'
})

2、函数类型接口

对方法传入的参数 以及返回值进行约束 批量约束

// 加密的函数类型接口
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;
}

console.log(sha1('name','lisi'));

3、可索引接口

数组、对象的约束 (不常用)

//ts定义数组的方式
var arr:number[]=[2342,235325]
var arr1:Array<string>=['111','222']

//可索引接口 对数组的约束
interface UserArr{
    [index:number]:string
}

var arr:UserArr=['aaa','bbb'];
console.log(arr[0]);

var arr:UserArr=[123,'bbb'];  /*错误*/
console.log(arr[0]);

// 索引接口 对对象的约束
interface UserObj{
    [index:string]:string
}
var arr:UserObj={name:'张三'};

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

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+'吃粮食')
    }
}

var d=new Dog('小黑');
d.eat();

class Cat implements Animal{
    name:string;
    constructor(name:string){

        this.name=name;

    }
    eat(food:string){

        console.log(this.name+'吃'+food);
    }
}

var c=new Cat('小花');
c.eat('老鼠');

5、接口扩展:接口可以继承接口

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+'写代码');
    }
}

var w=new Web('小李');

w.eat();
类可以继承类 再 实现接口
interface Animal{
    eat():void;
}

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

class Programmer{
    public name:string;
    constructor(name:string){
        this.name=name;
    }

    coding(code:string){
        console.log(this.name+code)
    }
}

class Web extends Programmer implements Person{
    constructor(name:string){
        super(name)
    }
    eat(){
        console.log(this.name+'喜欢吃馒头')
    }
    work(){
        console.log(this.name+'写代码');
    }
}

var w=new Web('小李');
// w.eat();
w.coding('写ts代码');

八、typeScript中的泛型

泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

对于没有泛型前:

1、只能返回string类型的数据
function getData(value:string):string{
    return value;
}
2、同时返回 string类型 和number类型 (代码冗余)
function getData1(value:string):string{
    return value;
}

function getData2(value:number):number{
    return value;
}

// 或者使用类的重载函数
3、同时返回 string类型 和number类型 any可以解决这个问题
function getData(value:any):any{
	return '哈哈哈';
}

getData(123);
getData('str');

any放弃了类型检查,传入什么 返回什么。比如:传入number 类型必须返回number类型 传入 string类型必须返回string类型

//传入的参数类型和返回的参数类型可以不一致
function getData(value:any):any{
	return '哈哈哈';
}
4、使用泛型 - 函数的使用

泛型:可以支持不特定的数据类型 要求:传入的参数和返回的参数一直。

T表示泛型,具体什么类型是调用这个方法的时候决定的。

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

getData<number>(123);
getData<string>('1214231');
getData<number>('2112');       /*错误的写法*/

function getData<T>(value:T):any{
    return '2145214214';
}

getData<number>(123);  //参数必须是number
getData<string>('这是一个泛型');
5、使用泛型 - 泛型类
class MinClas<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 MinClas<number>();   /*实例化类 并且制定了类的T代表的类型是number*/
m1.add(11);
m1.add(3);
m1.add(2);
alert(m1.min())

var m2=new MinClas<string>();   /*实例化类 并且制定了类的T代表的类型是string*/
m2.add('c');
m2.add('a');
m2.add('v');
alert(m2.min())
6、使用泛型 - 泛型接口

在不使用泛型前的类型接口:

interface ConfigFn{
    (value1:string,value2:string):string;
}

var setData:ConfigFn=function(value1:string,value2:string):string{
    return value1+value2;
}

setData('name','张三');

使用泛型的接口

interface ConfigFn{
    <T>(value:T):T;
}

var getData:ConfigFn=function<T>(value:T):T{
    return value;
}

getData<string>('张三');
getData<string>(1243);  //错误
interface ConfigFn<T>{
	(value:T):T;
}
function getData<T>(value:T):T{
	return value;
}
var myGetData:ConfigFn<string>=getData;

myGetData('20');  /*正确*/
// myGetData(20)  //错误
7、泛型类的使用

定义一个User的类这个类的作用就是映射数据库字段 然后定义一个 MysqlDb的类这个类用于操作数据库 然后把User类作为参数传入到MysqlDb中

var user=new User({
    username:'张三',
    password:'123456'
})

var Db=new MysqlDb();
Db.add(user);
//把类作为参数来约束数据传入的类型

class User{
    username:string | undefined;
    pasword:string | undefined;
}

class MysqlDb{
    add(user:User):boolean{

        console.log(user);
        return true;
    }

}
var u=new User();
u.username='张三';
u.pasword='123456';
var Db=new MysqlDb();
Db.add(u);

class ArticleCate{
    title:string | undefined;
    desc:string | undefined;
    status:number | undefined
}

class MysqlDb{
    add(info:ArticleCate):boolean{
        console.log(info);
        console.log(info.title);
        return true;
    }

}
var a=new ArticleCate();
a.title="国内";
a.desc="国内新闻";
a.status=1;

var Db=new MysqlDb();
Db.add(a);

问题:代码重复

使用泛型类定义数据

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;
    pasword:string | undefined;
}
var u=new User();
u.username='张三';
u.pasword='123456';
var Db=new MysqlDb<User>();
Db.add(u);

//2、相关ArticleCate增加数据 和数据库进行映射
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 a=new ArticleCate({
    title:'分类',
    desc:'1111',
    status:1
});

//类当做参数的泛型类
var Db=new MysqlDb<ArticleCate>();
Db.add(a);

//修改数据
var a=new ArticleCate({
        title:'分类111',
        desc:'2222'
});

a.status=0;
var Db=new MysqlDb<ArticleCate>();
Db.updated(a,12);