筆記:12:TypeScript

菜鳥教程:https://www.runoob.com/typescript/ts-basic-syntax.html

目錄

1、安裝
2、操作
3、配置自動(dòng)編譯
4、typeScript中的數(shù)據(jù)類型
5、typeScript中的數(shù)據(jù)類型簡(jiǎn)介
6、typeScript中的函數(shù)
7、es5創(chuàng)建對(duì)象繼承
8、typeScript中的類
9、typeScript中的接口
10、typeScript中的泛型
11、例子
12、模塊
13、命名空間
14、裝飾器
- 報(bào)錯(cuò)

正文

1、安裝

npm install -g typescript
// 驗(yàn)證是否安裝成功
tsc -v

2、操作

  • 創(chuàng)建test.ts文件
var message:string = "Hello World" 
console.log(message)
  • 執(zhí)行以下命令將 TypeScript 轉(zhuǎn)換為 JavaScript 代碼
tsc app.ts

3、配置自動(dòng)編譯

webStorm配置自動(dòng)編譯
webStorm配置自動(dòng)編譯ts
vscode配置自動(dòng)編譯
  • 第一步 tsc --init 生成tsconfig.json 改 "outDir": "./js",
  • 第二步 任務(wù) - 運(yùn)行任務(wù) 監(jiān)視tsconfig.json

4、typeScript中的數(shù)據(jù)類型

typescript中為了使編寫的代碼更規(guī)范,更有利于維護(hù),增加了類型校驗(yàn),在typescript中主要給我們提供了以下數(shù)據(jù)類型。

  • 布爾類型(boolean)
  • 數(shù)字類型(number)
  • 字符串類型(string)
  • 數(shù)組類型(array)
  • 元組類型(tuple)
  • 枚舉類型(enum)
  • 任意類型(any)
  • null 和 undefined
  • void類型
  • never類型

5、typeScript中的數(shù)據(jù)類型簡(jiǎn)介

  • ts代碼須指定類型
    typescript中為了使編寫的代碼更規(guī)范,更有利于維護(hù),增加了類型校驗(yàn)。寫ts代碼必須指定類型。
  • 布爾類型(boolean)
var flag:boolean=true;
// flag=123;  //錯(cuò)誤
flag=false;  //正確 
console.log(flag);
  • 數(shù)字類型(number)
var a:number = 123
console.log(a)

// a = 'string' // 錯(cuò)誤寫法
// a = false // 錯(cuò)誤寫法
a = 12.3
console.log(a)
  • 字符串類型(string)
let str:string = 'hahaha'
// str = 12 // 錯(cuò)誤寫法
str = '你好'
  • 數(shù)組類型(array):ts中定義數(shù)組有兩種方式
1.第一種定義數(shù)組的方式
var arr:number[]=[11,22,33];
console.log(arr);
let str:string[] = ['haha', 'hehe']
2.第二種定義數(shù)組的方式
var arr:Array<number>=[11,22,33];
console.log(arr)
3、第三種
var arr3:any[]=['131214',22,true];
console.log(arr3);
  • 元組類型(tuple) 屬于數(shù)組的一種
var arr:Array<number>=[11,22,33];
console.log(arr)

元祖類型
let arr:[number,string]=[123,'this is ts'];
console.log(arr);
  • 枚舉類型(enum)

隨著計(jì)算機(jī)的不斷普及,程序不僅只用于數(shù)值計(jì)算,還更廣泛地用于處理非數(shù)值的數(shù)據(jù)。
例如:性別、月份、星期幾、顏色、單位名、學(xué)歷、職業(yè)等,都不是數(shù)值數(shù)據(jù)。
在其它程序設(shè)計(jì)語言中,一般用一個(gè)數(shù)值來代表某一狀態(tài),這種處理方法不直觀,易讀性差。
如果能在程序中用自然語言中有相應(yīng)含義的單詞來代表某一狀態(tài),則程序就很容易閱讀和理解。
也就是說,事先考慮到某一變量可能取的值,盡量用自然語言中含義清楚的單詞來表示它的每一個(gè)值,
這種方法稱為枚舉方法,用這種方法定義的類型稱枚舉類型。

enum 枚舉名{ 
     標(biāo)識(shí)符[=整型常數(shù)], 
     標(biāo)識(shí)符[=整型常數(shù)], 
     ... 
     標(biāo)識(shí)符[=整型常數(shù)], 
} ;

flag    1:表示true;-1:表示false

enum Flag {success=1, error=-1}
var f:Flag = Flag.error
console.log(f)
console.log(Flag.error)

enum Color {red, blue=5, orange}
var c:Color = Color.red // 0
var c:Color = Color.blue // 5
var c:Color = Color.orange // 6
  • 任意類型(any)
var num:any=123;
num='str';
num=true;
console.log(num)
----------任意類型的用處
var oBox:any=document.getElementById('box');
oBox.style.color='red';
  • null 和 undefined:其他(never類型)數(shù)據(jù)類型的子類型。
var num:number;
console.log(num)  // 輸出:undefined   報(bào)錯(cuò)

var num:undefined;
console.log(num)  //輸出:undefined  //正確

var num:number | undefined;
num=123;
console.log(num);

//定義沒有賦值就是undefined
var num:number | undefined;
console.log(num);

var num:null;
num=null;

//一個(gè)元素可能是 number類型 可能是null 可能是undefined
var num:number | null | undefined;
num=1234;
console.log(num)
  • void類型:typescript中的void表示沒有任何類型,一般用于定義方法的時(shí)候方法沒有返回值。
// 正確寫法
function run():void{
    console.log('run')
}
run();

//錯(cuò)誤寫法
function run():undefined{
    console.log('run')
}
run();

//正確寫法
function run():number{
   return 123;
}
run();
  • never類型:是其他類型 (包括 null 和 undefined)的子類型,代表從不會(huì)出現(xiàn)的值。這意味著聲明never的變量只能被never類型所賦值。
var a:undefined;
a=undefined;

var b:null;
b=null;

var a:never;
// a=123; //錯(cuò)誤的寫法
// 正確寫法,一般用不到
a=(()=>{
    throw new Error('錯(cuò)誤');
})()

6、typeScript中的函數(shù)

(1)函數(shù)的定義

******es5定義函數(shù)的方法
// 函數(shù)聲明法
function run(){

    return 'run';
}
// 匿名函數(shù)
var run2=function(){
    return 'run2';
}
******ts中定義函數(shù)的方法
// 函數(shù)聲明法
function run():string{
    return 'run';
}
錯(cuò)誤寫法
function run():string{
    return 123;
}
// 匿名函數(shù)
var fun2=function():number{
    return 123;
}
alert(fun2()); /*調(diào)用方法*/

******ts中定義方法傳參
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)方法可選參數(shù)

******es5里面方法的實(shí)參和行參可以不一樣,但是ts中必須一樣,如果不一樣就需要配置可選參數(shù)。
function getInfo(name:string,age?:number):string{
    if(age){
        return `${name} --- ${age}`;
    } else {
        return `${name} ---年齡保密`;
    }
}
alert(getInfo('zhangsan'))
alert(getInfo('zhangsan',123))

!!!!!!注意:可選參數(shù)必須配置到參數(shù)的最后面

錯(cuò)誤寫法
function getInfo(name?:string,age:number):string{
    if(age){
        return `${name} --- ${age}`;
    }else{
        return `${name} ---年齡保密`;
    }
}
alert(getInfo('zhangsan'))

(3)默認(rèn)參數(shù)(也稱可選參數(shù))

******es5里面沒法設(shè)置默認(rèn)參數(shù),es6和ts中都可以設(shè)置默認(rèn)參數(shù)。
function getInfo(name:string,age:number=20):string{
    if(age){
        return `${name} --- ${age}`;
    }else{
        return `${name} ---年齡保密`;
    }
}
alert( getInfo('張三',30));

(4)剩余參數(shù)

function sum(a:number,b:number,c:number,d:number):number{
    return a+b+c+d;
}
alert(sum(1,2,3,4)) ;

******三點(diǎn)運(yùn)算符 接受新參傳過來的值
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)) ;

(5)ts函數(shù)重載

java中方法的重載:重載指的是兩個(gè)或者兩個(gè)以上同名函數(shù),但它們的參數(shù)不一樣,這時(shí)會(huì)出現(xiàn)函數(shù)重載的情況。
typescript中的重載:通過為同一個(gè)函數(shù)提供多個(gè)函數(shù)類型定義來試下多種功能的目的。
ts為了兼容es5 以及 es6 重載的寫法和java中有區(qū)別。
// es5中出現(xiàn)同名方法,下面的會(huì)替換上面的方法 
function css(config){
}

function css(config,value){
}

// ts中的重載
function getInfo(name:string):string;
function getInfo(age:number):number;
function getInfo(str:any):any{
    if(typeof str==='string'){
        return '我叫:'+str;
    }else{
        return '我的年齡是'+str;
    }
}
alert(getInfo('張三'));   //正確
alert(getInfo(20));   //正確
alert(getInfo(true));    //錯(cuò)誤寫法

// 可選參數(shù)
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));  // 錯(cuò)誤
// alert(getInfo('zhangsan',20));

(6)箭頭函數(shù)(es6)

!!!this指向的問題:箭頭函數(shù)里面的this指向上下文
// es5
setTimeout(function(){
    alert('run')
},1000)

// es6
setTimeout(()=>{
    alert('run')
},1000)

7、es5創(chuàng)建對(duì)象繼承

(1)最簡(jiǎn)單的類

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

(2)構(gòu)造函數(shù)和原型鏈里面增加方法

function Person(){
    this.name='張三';  /*屬性*/
    this.age=20;
    this.run=function(){
        alert(this.name+'在運(yùn)動(dòng)');
    }
}
//原型鏈上面的屬性會(huì)被多個(gè)實(shí)例共享   構(gòu)造函數(shù)不會(huì)
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}
var p=new Person();
// alert(p.name);
// p.run();
p.work();

(3)類里面的靜態(tài)方法:直接調(diào)用;實(shí)例方法:需要new才能調(diào)用

function Person(){
    this.name='張三';  /*屬性*/
    this.age=20;
    this.run=function(){  /*實(shí)例方法:需要new才能調(diào)用*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}

Person.getInfo=function(){
    alert('我是靜態(tài)方法');
}
//原型鏈上面的屬性會(huì)被多個(gè)實(shí)例共享   構(gòu)造函數(shù)不會(huì)
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');

}
var p=new Person();    
p.work();

//調(diào)用靜態(tài)方法
Person.getInfo(); // 直接調(diào)用

(4)es5里面的繼承:對(duì)象冒充實(shí)現(xiàn)繼承

function Person(){
    this.name='張三';  /*屬性*/
    this.age=20;
    this.run=function(){  /*實(shí)例方法*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
     alert(this.name+'在工作');
}

//Web類 繼承Person類 
function Web(){
    Person.call(this);    /*對(duì)象冒充實(shí)現(xiàn)繼承*/
}

var w=new Web();
// w.run();  // 對(duì)象冒充可以繼承構(gòu)造函數(shù)里面的屬性和方法
w.work();  // 對(duì)象冒充可以繼承構(gòu)造函數(shù)里面的屬性和方法,但是沒法繼承原型鏈上面的屬性和方法

(5)es5里面的繼承:原型鏈實(shí)現(xiàn)繼承

function Person(){
    this.name='張三';  /*屬性*/
    this.age=20;
    this.run=function(){  /*實(shí)例方法*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
     alert(this.name+'在工作');
}

//Web類 繼承Person類   原型鏈+對(duì)象冒充的組合繼承模式

function Web(){
}
Web.prototype=new Person();   //原型鏈實(shí)現(xiàn)繼承
var w=new Web();
//原型鏈實(shí)現(xiàn)繼承:可以繼承構(gòu)造函數(shù)里面的屬性和方法,也可以繼承原型鏈上面的屬性和方法。
//w.run();
w.work();

(6)原型鏈實(shí)現(xiàn)繼承的問題?無法傳參

function Person(name,age){
    this.name=name;  /*屬性*/
    this.age=age;
    this.run=function(){  /*實(shí)例方法*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
     alert(this.name+'在工作');
}
var p=new Person('李四',20);
p.run();
 
// 原型鏈繼承
function Person(name,age){
    this.name=name;  /*屬性*/
    this.age=age;
    this.run=function(){  /*實(shí)例方法*/
    alert(this.name+'在運(yùn)動(dòng)');
}
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}

function Web(name,age){        
}
Web.prototype=new Person();
var w=new Web('趙四',20);   //實(shí)例化子類的時(shí)候沒法給父類傳參
w.run(); // undefined在運(yùn)動(dòng)

(7)原型鏈+對(duì)象冒充的組合繼承模式(第一種)

function Person(name,age){
    this.name=name;  /*屬性*/
    this.age=age;
    this.run=function(){  /*實(shí)例方法*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}
function Web(name,age){
    Person.call(this,name,age);   //對(duì)象冒充繼承   實(shí)例化子類可以給父類傳參
}
Web.prototype=new Person();
var w=new Web('趙四',20);   //實(shí)例化子類的時(shí)候沒法給父類傳參
w.run();
w.work();

(8)原型鏈+對(duì)象冒充的組合繼承模式(第二種)

function Person(name,age){
    this.name=name;  /*屬性*/
    this.age=age;
    this.run=function(){  /*實(shí)例方法*/
        alert(this.name+'在運(yùn)動(dòng)');
    }
}      
Person.prototype.sex="男";
Person.prototype.work=function(){
    alert(this.name+'在工作');
}
  
function Web(name,age){
    Person.call(this,name,age);   //對(duì)象冒充繼承  可以繼承構(gòu)造函數(shù)里面的屬性和方法、實(shí)例化子類可以給父類傳參
}
Web.prototype=Person.prototype;
var w=new Web('趙四',20);   //實(shí)例化子類的時(shí)候沒法給父類傳參
w.run();
w.work();

8、typeScript中的類

(1)類的定義

es5:
    function Person(name){
        this.name=name;
        this.run=function(){
            console.log(this.name)
        }
    }
    var p=new Person('張三');
    p.run()
***************************************************************************
ts中定義類:
    class Person{
        name:string;   //屬性  前面省略了public關(guān)鍵詞
        constructor(n:string){  //構(gòu)造函數(shù)   實(shí)例化類的時(shí)候觸發(fā)的方法
            this.name=n;
        }
        run():void{
            alert(this.name);
        }
    }
    var p=new Person('張三');
    p.run()
---------------------------------------------------------------------
    class Person{
        name:string; 
        constructor(name:string){  //構(gòu)造函數(shù)   實(shí)例化類的時(shí)候觸發(fā)的方法
            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中實(shí)現(xiàn)繼承:extends、super

class Person{
    name:string;
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在運(yùn)動(dòng)`
    }
}
var p=new Person('王五');
alert(p.run())

class Web extends Person{
    constructor(name:string){
        super(name);  /*初始化父類的構(gòu)造函數(shù)*/
    }
}
var w=new Web('李四');
alert(w.run());
***********************************************************
ts中繼承的探討:父類的方法和子類的方法一致
    class Person{
        name:string;
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    // var p=new Person('王五');
    // alert(p.run())
    
    class Web extends Person{
        constructor(name:string){
            super(name);  /*初始化父類的構(gòu)造函數(shù)*/
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)-子類`
        }
        work(){
            alert(`${this.name}在工作`)
        }
    }
    var w=new Web('李四');
    alert(w.run());
    w.work();
    alert(w.run());

(3)類里面的修飾符:typescript里面定義屬性的時(shí)候給我們提供了三種修飾符。

  • public:公有。在當(dāng)前類里面、子類、類外面都可以訪問。
  • protected:保護(hù)類型。在當(dāng)前類里面、子類里面可以訪問,在類外部沒法訪問。
  • private :私有。在當(dāng)前類里面可以訪問,子類、類外部都沒法訪問。
    !!!屬性如果不加修飾符,默認(rèn)就是:公有(public)。
1、public:公有。在類里面、子類、類外面都可以訪問。
    class Person{
        public name:string;  /*公有屬性*/
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    var p=new Person('王五');
    alert(p.run())
    
    class Web extends Person{
        constructor(name:string){
            super(name);  /*初始化父類的構(gòu)造函數(shù)*/
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)-子類`
        }
        work(){
            alert(`${this.name}在工作`)
        }
    }
    var w=new Web('李四');
    w.work();
    ---------------------------------
    類外部訪問公有屬性
    class Person{
        public name:string;  /*公有屬性*/
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    var  p=new Person('哈哈哈');
    alert(p.name);
*******************************************************************************
2、protected:保護(hù)類型。在類里面、子類里面可以訪問,在類外部沒法訪問。
    class Person{
        protected name:string;  /*公有屬性*/
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    var p=new Person('王五');
    alert(p.run())
    
    class Web extends Person{
        constructor(name:string){
            super(name);  /*初始化父類的構(gòu)造函數(shù)*/
        }                  
        work(){
            alert(`${this.name}在工作`)
        }
    }
    var w=new Web('李四11');
    w.work();
    alert( w.run());
    ----------------------------
    類外外部沒法訪問保護(hù)類型的屬性
    class Person{
        protected name:string;  /*保護(hù)類型*/
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    var p=new Person('哈哈哈');
    alert(p.name);
*******************************************************************************
3、private:私有。在類里面可以訪問,子類、類外部都沒法訪問。
    class Person{
        private name:string;  /*私有*/
        constructor(name:string){
            this.name=name;
        }
        run():string{
            return `${this.name}在運(yùn)動(dòng)`
        }
    }
    var p=new Person('哈哈哈');
    alert(p.run()); // 訪問不到

(4)靜態(tài)屬性、靜態(tài)方法

function Person(){
    this.run1=function(){ // 實(shí)例方法
    }
}
Person.name='哈哈哈';
Person.run2=function(){  // 靜態(tài)方法
}
var p=new Person();
Person.run2(); // 靜態(tài)方法的調(diào)用
-------------------------------------------------------
例子:jQuery
    function $(element){
        return new Base(element)
    }
    $.get=function(){
    }
    function Base(element){
        this.element=獲取dom節(jié)點(diǎn);
        this.css=function(arr,value){
            this.element.style.arr=value;
        }
    }
    $('#box').css('color','red')
    $.get('url',function(){
    })
**********************************************
    class Per{
        public name:string;
        public age:number=20;
        //靜態(tài)屬性
        static sex="男";
        constructor(name:string) {
                this.name=name;
        }
        run(){  /*實(shí)例方法*/
            alert(`${this.name}在運(yùn)動(dòng)`)
        }
        work(){
            alert(`${this.name}在工作`)
        }
        static print(){  /*靜態(tài)方法:里面沒法通過this來直接調(diào)用類里面的屬性*/
            alert('print方法'+Per.sex);
        }
    }
    // var p=new Per('張三');
    // p.run();
    Per.print();
    alert(Per.sex);

(5)抽象類:多態(tài):父類定義一個(gè)方法不去實(shí)現(xiàn),讓繼承它的子類去實(shí)現(xiàn),每一個(gè)子類有不同的表現(xiàn)。多態(tài)屬于繼承。

class Animal {
    name:string;
    constructor(name:string) {
        this.name=name;
    }
    eat(){   // 具體吃什么,不知道。具體吃什么?繼承它的子類去實(shí)現(xiàn) ,每一個(gè)子類的表現(xiàn)不一樣。
        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+'吃老鼠'
    }
}
  • typescript中的抽象類:它是提供其他類繼承的基類,不能直接被實(shí)例化。
  • 用abstract關(guān)鍵字定義抽象類和抽象方法,抽象類中的抽象方法不包含具體實(shí)現(xiàn)并且必須在派生類中實(shí)現(xiàn)。
  • abstract抽象方法只能放在抽象類里面。
  • 抽象類和抽象方法用來定義標(biāo)準(zhǔn) 。標(biāo)準(zhǔn):Animal 這個(gè)類要求它的子類必須包含eat方法。
// 標(biāo)準(zhǔn):
abstract class Animal{
    public name:string;
    constructor(name:string){
        this.name=name;
    }
    abstract eat():any;  //抽象方法不包含具體實(shí)現(xiàn)并且必須在派生類中實(shí)現(xiàn)。
    run(){
        console.log('其他方法可以不實(shí)現(xiàn)')
    }
}
// var a=new Animal() /*錯(cuò)誤的寫法*/

class Dog extends Animal{
    //抽象類的子類必須實(shí)現(xiàn)抽象類里面的抽象方法
    constructor(name:any){
        super(name)
    }
    eat(){
        console.log(this.name+'吃糧食')
    }
}
var d=new Dog('小花花');
d.eat();

class Cat extends Animal{
    //抽象類的子類必須實(shí)現(xiàn)抽象類里面的抽象方法
    constructor(name:any){
        super(name)
    }
    run(){
    }
    eat(){
        console.log(this.name+'吃老鼠')
    }
}
var c=new Cat('小花貓');
c.eat();

9、typeScript中的接口

接口的作用:在面向?qū)ο蟮木幊讨校涌谑且环N規(guī)范的定義,它定義了行為和動(dòng)作的規(guī)范,在程序設(shè)計(jì)里面,接口起到一種限制和規(guī)范的作用。接口定義了某一批類所需要遵守的規(guī)范,接口不關(guān)心這些類的內(nèi)部狀態(tài)數(shù)據(jù),也不關(guān)心這些類里方法的實(shí)現(xiàn)細(xì)節(jié),它只規(guī)定這批類里必須提供某些方法,提供這些方法的類就可以滿足實(shí)際需要。
用來定義標(biāo)準(zhǔn)。

(1)屬性類接口:對(duì)json的約束。

ts中定義方法
    function printLabel():void {
        console.log('printLabel');
    }
    printLabel();
ts中定義方法傳入?yún)?shù)
    function printLabel(label:string):void {
        console.log('printLabel');
    }
    printLabel('hahah');
ts中自定義方法傳入?yún)?shù),對(duì)json進(jìn)行約束
    function printLabel(labelInfo:{label:string}):void {
        console.log('printLabel');
    }
    printLabel('hahah'); //錯(cuò)誤寫法
    printLabel({name:'張三'});  //錯(cuò)誤的寫法
    printLabel({label:'張三'});  //正確的寫法
*************************************************************
接口:行為和動(dòng)作的規(guī)范,對(duì)批量方法傳入?yún)?shù)進(jìn)行約束。
    就是傳入對(duì)象的約束、屬性接口
    interface FullName{
        firstName:string;   //注意;結(jié)束
        secondName:string;
    }
    function printName(name:FullName){
        // 必須傳入對(duì)象  firstName  secondName
        console.log(name.firstName+'--'+name.secondName);
    }
    // printName('1213');  //錯(cuò)誤
    var obj={   /*傳入的參數(shù)必須包含 firstName  secondName*/
        age:20,
        firstName:'張',
        secondName:'三'
    };
    printName(obj)
    -----------------------------------------------------------------
    interface FullName{
        firstName:string;   //注意;結(jié)束
        secondName:string;
    }

    function printName(name:FullName){
        // 必須傳入對(duì)象  firstName  secondName
        console.log(name.firstName+'--'+name.secondName);
    }
    function printInfo(info:FullName){
        // 必須傳入對(duì)象  firstName  secondName
        console.log(info.firstName+info.secondName);
    }

    var obj={   /*傳入的參數(shù)必須包含 firstName  secondName*/
        age:20,
        firstName:'張',
        secondName:'三'
    };
    printName(obj);
    printInfo({
        firstName:'李',
        secondName:'四'
    })
接口 :參數(shù)順序
    interface FullName{
        firstName:string;
        secondName:string;
    }

    function getName(name:FullName){
        console.log(name)
    }
    //參數(shù)的順序可以不一樣
    getName({        
        secondName:'secondName',
        firstName:'firstName'
    })
接口 :可選屬性
    interface FullName{
        firstName:string;
        secondName?:string; // ?:可選屬性
    }

    function getName(name:FullName){
        console.log(name)
    }  
    getName({               
        firstName:'firstName'
    })
****************************************************************
例子
    //原生js封裝的ajax
    interface Config{
        type:string;
        url:string;
        data?:string;
        dataType:string;
    }

    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)函數(shù)類型接口:對(duì)方法傳入的參數(shù),以及返回值進(jìn)行約束。批量約束。

例子:加密的函數(shù)類型接口
    interface encrypt{
        (key:string,value:string):string; // 不需要寫function
    }

    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)可索引接口:數(shù)組、對(duì)象的約束。(不常用)

ts定義數(shù)組的方式
    var arr:number[]=[2342,235325]
    var arr1:Array<string>=['111','222']
******************************************
可索引接口:對(duì)數(shù)組的約束。
    interface UserArr{
        [index:number]:string
    }

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

    var arr:UserArr=[123,'bbb'];  /*錯(cuò)誤*/
    console.log(arr[0]); /*錯(cuò)誤*/
可索引接口:對(duì)對(duì)象的約束。
    interface UserObj{
        [index:string]:string
    }

    var arr:UserObj={name:'張三'};

(4)類類型接口:對(duì)類的約束。和抽象類抽象有點(diǎn)相似。

    interface Animal{
        name:string;
        eat(str:string):void; // 不傳參數(shù)也可以
    }

    class Dog implements Animal{ // 實(shí)現(xiàn)接口
        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)接口擴(kuò)展:接口可以繼承接口

    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{ // 繼承+實(shí)現(xiàn)
        constructor(name:string){
           super(name)
        }
        eat(){
            console.log(this.name+'喜歡吃饅頭')
        }
        work(){
            console.log(this.name+'寫代碼');
        }
    }
    var w=new Web('小李');
    // w.eat();
    w.coding('寫ts代碼'); // 繼承來的

10、typeScript中的泛型

(1)泛型定義

  • 泛型:軟件工程中,我們不僅要?jiǎng)?chuàng)建一致的定義良好的API,同時(shí)也要考慮可重用性。組件不僅能夠支持當(dāng)前的數(shù)據(jù)類型,同時(shí)也能支持未來的數(shù)據(jù)類型,這在創(chuàng)建大型系統(tǒng)時(shí)為你提供了十分靈活的功能。
  • 在像C#和Java這樣的語言中,可以使用泛型來創(chuàng)建可重用的組件,一個(gè)組件可以支持多種類型的數(shù)據(jù)。 這樣用戶就可以以自己的數(shù)據(jù)類型來使用組件。
  • 通俗理解:泛型就是解決:類、接口、方法的復(fù)用性、以及對(duì)不特定數(shù)據(jù)類型的支持(類型校驗(yàn))。
只能返回string類型的數(shù)據(jù)
    function getData(value:string):string{
        return value;
    }
同時(shí)返回 string類型 和number類型  (代碼冗余)
    function getData1(value:string):string{
        return value;
    }
    function getData2(value:number):number{
        return value;
    }
同時(shí)返回 string類型 和number類型。any可以解決這個(gè)問題。
    function getData(value:any):any{
        return '哈哈哈';
    }
    getData(123);
    getData('str');
!!!any放棄了類型檢查,傳入什么,返回什么。比如:傳入number 類型必須返回number類型。傳入string類型必須返回string類型。
傳入的參數(shù)類型和返回的參數(shù)類型可以不一致
    function getData(value:any):any{
        return '哈哈哈';
    }

(2)泛型函數(shù)

  • 泛型:可以支持不特定的數(shù)據(jù)類型。要求:傳入的參數(shù)和返回的參數(shù)一致。
  • T表示泛型,具體什么類型是調(diào)用這個(gè)方法的時(shí)候決定的。
function getData<T>(value:T):T{
    return value;
}
getData<number>(123);
getData<string>('1214231');
getData<number>('2112');       /*錯(cuò)誤的寫法*/  
--------------------------------------------
function getData<T>(value:T):any{
    return '2145214214';
}
getData<number>(123);  //參數(shù)必須是number
getData<string>('這是一個(gè)泛型');

(3)泛型類:比如有個(gè)最小堆算法,需要同時(shí)支持返回?cái)?shù)字和字符串 a - z兩種類型。通過類的泛型來實(shí)現(xiàn)。

class MinClass{
    public list:number[]=[];
    add(num:number){
        this.list.push(num)
    }
    min():number{
        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 m=new MinClass();

m.add(3);
m.add(22);
m.add(23);
m.add(6);
m.add(7);
alert(m.min());
  • 類的泛型
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>();   /*實(shí)例化類 并且制定了類的T代表的類型是number*/
m1.add(11);
m1.add(3);
m1.add(2);
alert(m1.min())

var m2=new MinClas<string>();   /*實(shí)例化類 并且制定了類的T代表的類型是string*/
m2.add('c');
m2.add('a');
m2.add('v');
alert(m2.min())
  • 定義一個(gè)User的類,這個(gè)類的作用就是映射數(shù)據(jù)庫字段,然后定義一個(gè) MysqlDb的類這個(gè)類用于操作數(shù)據(jù)庫,然后把User類作為參數(shù)傳入到MysqlDb中。
var user=new User({
    username:'張三',
    password:'123456'
})
var Db=new MysqlDb();
Db.add(user);
  • (例子1)問題:代碼重復(fù)
// 把類作為參數(shù)來約束數(shù)據(jù)傳入的類型 
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="國(guó)內(nèi)";
a.desc="國(guó)內(nèi)新聞";
a.status=1;
var Db=new MysqlDb();
Db.add(a);
  • (例子2)
定義操作數(shù)據(jù)庫的泛型類
    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;
        }
    }
*********************************************************************
1、想給User表增加數(shù)據(jù),定義一個(gè)User類,和數(shù)據(jù)庫進(jìn)行映射。
    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增加數(shù)據(jù),定義一個(gè)ArticleCate類,和數(shù)據(jù)庫進(jìn)行映射。
    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
        });
        //類當(dāng)做參數(shù)的泛型類
        var Db=new MysqlDb<ArticleCate>();
        Db.add(a);

    修改數(shù)據(jù)
        var a=new ArticleCate({ // 實(shí)例化傳值
            title:'分類111',
            desc:'2222'
        });
        a.status=0;
        var Db=new MysqlDb<ArticleCate>();
        Db.updated(a,12);

(4)泛型接口

函數(shù)類型接口
    interface ConfigFn{
        (value1:string,value2:string):string;
    }
    var setData:ConfigFn = function(value1:string,value2:string):string{
        return value1+value2;
    }
    setData('name','張三');
1、泛型接口
    interface ConfigFn{
        <T>(value:T):T;
    }

    var getData:ConfigFn=function<T>(value:T):T{
        return value;
    }
    // getData<string>('張三');
    // getData<string>(1243);  //錯(cuò)誤
2、泛型接口
    interface ConfigFn<T>{
        (value:T):T;
    }
    function getData<T>(value:T):T{
        return value;
    }        
    var myGetData:ConfigFn<string>=getData; // myGetData實(shí)現(xiàn)ConfigFn這個(gè)泛型
    myGetData('20');  /*正確*/
    // myGetData(20)  //錯(cuò)誤

11、例子

  • 功能:定義一個(gè)操作數(shù)據(jù)庫的庫 支持 Mysql Mssql MongoDb
  • 要求1:Mysql MsSql MongoDb功能一樣 都有 add update delete get方法
  • 注意:約束統(tǒng)一的規(guī)范、以及代碼重用
  • 解決方案:需要約束規(guī)范所以要定義接口 ,需要代碼重用所以用到泛型
    1、接口:在面向?qū)ο蟮木幊讨?,接口是一種規(guī)范的定義,它定義了行為和動(dòng)作的規(guī)范
    2、泛型 通俗理解:泛型就是解決 類 接口 方法的復(fù)用性
標(biāo)準(zhǔn)
    interface DBI<T>{
        add(info:T):boolean;
        update(info:T,id:number):boolean;
        delete(id:number):boolean;
        get(id:number):any[];
    }
**************************************************************************************
定義一個(gè)操作mysql數(shù)據(jù)庫的類.注意:要實(shí)現(xiàn)泛型接口 這個(gè)類也應(yīng)該是一個(gè)泛型類
    class MysqlDb<T> implements DBI<T>{
        constructor(){
            console.log('數(shù)據(jù)庫建立連接');
        }
        add(info: T): boolean {
            console.log(info);
            return true;
        }    
        update(info: T, id: number): boolean {
            throw new Error("Method not implemented.");
        }
        delete(id: number): boolean {
            throw new Error("Method not implemented.");
        }
        get(id: number): any[] {
            var list=[
                {
                    title:'xxxx',
                    desc:'xxxxxxxxxx'
                },
                {
                    title:'xxxx',
                    desc:'xxxxxxxxxx'
                }
            ]
            return list;
        }
    }
---------------------------------------------------------------------------
定義一個(gè)操作mssql數(shù)據(jù)庫的類
    class MsSqlDb<T> implements DBI<T>{
        constructor(){
            console.log('數(shù)據(jù)庫建立連接');
        }
        add(info: T): boolean {
            console.log(info);
            return true;
        }    
        update(info: T, id: number): boolean {
            throw new Error("Method not implemented.");
        }
        delete(id: number): boolean {
            throw new Error("Method not implemented.");
        }
        get(id: number): any[] {
            var list=[
                {
                    title:'xxxx',
                    desc:'xxxxxxxxxx'
                },
                {
                    title:'xxxx',
                    desc:'xxxxxxxxxx'
                }
            ]
            return list;
        }
    }
***********************************************************
操作用戶表:定義一個(gè)User類和數(shù)據(jù)表做映射
    class User{
        username:string | undefined;
        password:string | undefined;
    }
    var u=new User();
    u.username='張三111';
    u.password='123456';
    var oMysql=new MysqlDb<User>(); //類作為參數(shù)來約束數(shù)據(jù)傳入的類型 
    oMysql.add(u);
    ------------------------------------------------------------------------------
    class User{
        username:string | undefined;
        password:string | undefined;
    }
    var u=new User();
    u.username='張三2222';
    u.password='123456';
    var oMssql=new MsSqlDb<User>();
    oMssql.add(u);
    //獲取User表 ID=4的數(shù)據(jù)
    var data=oMssql.get(4);
    console.log(data);

12、模塊

(1)概念

  • 官方
關(guān)于術(shù)語的一點(diǎn)說明: 請(qǐng)務(wù)必注意一點(diǎn),TypeScript 1.5里術(shù)語名已經(jīng)發(fā)生了變化。 “內(nèi)部模塊”現(xiàn)在稱做“命名空間”。
“外部模塊”現(xiàn)在則簡(jiǎn)稱為“模塊” 模塊在其自身的作用域里執(zhí)行,而不是在全局作用域里;
這意味著定義在一個(gè)模塊里的變量,函數(shù),類等等在模塊外部是不可見的,除非你明確地使用export形式之一導(dǎo)出它們。 
相反,如果想使用其它模塊導(dǎo)出的變量,函數(shù),類,接口等的時(shí)候,你必須要導(dǎo)入它們,可以使用 import形式之一。
  • 自己理解
我們可以把一些公共的功能單獨(dú)抽離成一個(gè)文件作為一個(gè)模塊。
模塊里面的變量 函數(shù) 類等默認(rèn)是私有的,如果我們要在外部訪問模塊里面的數(shù)據(jù)(變量、函數(shù)、類),
我們需要通過export暴露模塊里面的數(shù)據(jù)(變量、函數(shù)、類...)。
暴露后我們通過 import 引入模塊就可以使用模塊里面暴露的數(shù)據(jù)(變量、函數(shù)、類...)。

13、命名空間

  • 在代碼量較大的情況下,為了避免各種變量命名相沖突,可將相似功能的函數(shù)、類、接口等放置到命名空間內(nèi)。
  • 同Java的包、.Net的命名空間一樣,TypeScript的命名空間可以將代碼包裹起來,只對(duì)外暴露需要在外部訪問的對(duì)象。命名空間內(nèi)的對(duì)象通過export關(guān)鍵字對(duì)外暴露。
  • 命名空間和模塊的區(qū)別:
    命名空間:內(nèi)部模塊,主要用于組織代碼,避免命名沖突。
    模塊:ts的外部模塊的簡(jiǎn)稱,側(cè)重代碼的復(fù)用,一個(gè)模塊里可能會(huì)有多個(gè)命名空間。
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} 吃貓糧。`);
        }
    }   
}
var d = new A.Dog('狼狗')
d.eat()
-------------------------------------------------------------------------------
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} 在吃貓糧。`);
        }
    }   
}
var c=new B.Cat('小花');
c.eat();

14、裝飾器

  • 裝飾器:裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,屬性或參數(shù)上,可以修改類的行為。
  • 通俗的講裝飾器就是一個(gè)方法,可以注入到類、方法、屬性參數(shù)上來擴(kuò)展類、屬性、方法、參數(shù)的功能。
  • 常見的裝飾器有:類裝飾器、屬性裝飾器、方法裝飾器、參數(shù)裝飾器。
  • 裝飾器的寫法:普通裝飾器(無法傳參)、裝飾器工廠(可傳參)。
  • 裝飾器是過去幾年中js最大的成就之一,已是Es7的標(biāo)準(zhǔn)特性之一。

(1)類裝飾器:類裝飾器在類聲明之前被聲明(緊靠著類聲明)。類裝飾器應(yīng)用于類構(gòu)造函數(shù),可以用來監(jiān)視,修改或替換類定義。傳入一個(gè)參數(shù)。

  • 類裝飾器:普通裝飾器(無法傳參)
function logClass(params:any){
    console.log(params);
    // params 就是當(dāng)前類
    params.prototype.apiUrl='動(dòng)態(tài)擴(kuò)展的屬性';
    params.prototype.run=function(){
        console.log('我是一個(gè)run方法');
    }
}

@logClass
class HttpClient{
    constructor(){
    }
    getData(){
    }
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
  • 類裝飾器:裝飾器工廠(可傳參)
function logClass(params:string){
    return function(target:any){
        console.log(target);
        console.log(params);
        target.prototype.apiUrl=params;
    }
}

@logClass('http://www.itying.com/api')
class HttpClient{
    constructor(){
    }
    getData(){
    }
}
var http:any=new HttpClient();
console.log(http.apiUrl);
  • 例子
下面是一個(gè)重載構(gòu)造函數(shù)的例子。
類裝飾器表達(dá)式會(huì)在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用,類的構(gòu)造函數(shù)作為其唯一的參數(shù)。
如果類裝飾器返回一個(gè)值,它會(huì)使用提供的構(gòu)造函數(shù)來替換類的聲明。
function logClass(target:any){
    console.log(target);
    return class extends target{
        apiUrl:any='我是修改后的數(shù)據(jù)';
        getData(){
            this.apiUrl=this.apiUrl+'----';
            console.log(this.apiUrl);
        }
    }
}

@logClass
class HttpClient{
    public apiUrl:string | undefined;
    constructor(){
        this.apiUrl='我是構(gòu)造函數(shù)里面的apiUrl';
    }
    getData(){
        console.log(this.apiUrl);
    }
}
var http=new HttpClient();
http.getData();

(2)屬性裝飾器
屬性裝飾器表達(dá)式會(huì)在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用,傳入下列2個(gè)參數(shù):

  • 對(duì)于靜態(tài)成員來說是類的構(gòu)造函數(shù),對(duì)于實(shí)例成員是類的原型對(duì)象。
  • 成員的名字。
類裝飾器
    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);
            console.log(attr);
            target[attr]=params;
        }
    }
    @logClass('xxxx')
    class HttpClient{
        @logProperty('http://itying.com')
        public url:any |undefined;
        constructor(){
        }
        getData(){
            console.log(this.url);
        }
    }
    var http=new HttpClient();
    http.getData();

(3)方法裝飾器
它會(huì)被應(yīng)用到方法的屬性描述符上,可以用來監(jiān)視,修改或者替換方法定義。
方法裝飾會(huì)在運(yùn)行時(shí)傳入下列3個(gè)參數(shù):

  • 對(duì)于靜態(tài)成員來說是類的構(gòu)造函數(shù),對(duì)于實(shí)例成員是類的原型對(duì)象。
  • 成員的名字。
  • 成員的屬性描述符。
方法裝飾器一
    function get(params:any){
        return function(target:any,methodName:any,desc:any){
            console.log(target);
            console.log(methodName);
            console.log(desc);
            target.apiUrl='xxxx';
            target.run=function(){
                console.log('run');
            }
        }
    }
    class HttpClient{  
        public url:any |undefined;
        constructor(){
        }
        @get('http://www.itying,com')
        getData(){
            console.log(this.url);
        }
    }
    var http:any=new HttpClient();
    console.log(http.apiUrl);
    http.run();
---------------------------------------------------------------------
方法裝飾器二
    function get(params:any){
        return function(target:any,methodName:any,desc:any){
            console.log(target);
            console.log(methodName);
            console.log(desc.value);       
            //修改裝飾器的方法  把裝飾器方法里面?zhèn)魅氲乃袇?shù)改為string類型
            //1、保存當(dāng)前的方法
            var oMethod=desc.value;
            desc.value=function(...args:any[]){                
                args=args.map((value)=>{
                    return String(value);
                })
                oMethod.apply(this,args);
            }
        }
    }
    class HttpClient{  
        public url:any |undefined;
        constructor(){
        }
        @get('http://www.itying,com')
        getData(...args:any[]){
            console.log(args);
            console.log('我是getData里面的方法');
        }
    }
    var http=new HttpClient();
    http.getData(123,'xxx');

(4)方法參數(shù)裝飾器
參數(shù)裝飾器表達(dá)式會(huì)在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用,可以使用參數(shù)裝飾器為類的原型增加一些元素?cái)?shù)據(jù) ,傳入下列3個(gè)參數(shù):

  • 對(duì)于靜態(tài)成員來說是類的構(gòu)造函數(shù),對(duì)于實(shí)例成員是類的原型對(duì)象。
  • 方法的名字。
  • 參數(shù)在函數(shù)參數(shù)列表中的索引。
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('xxxxx') uuid:any){
        console.log(299299, uuid);
    }
}
var http:any = new HttpClient();
http.getData(123456);
console.log( http.apiUrl);

(5)裝飾器執(zhí)行順序

  • 屬性》方法》方法參數(shù)》類
  • 如果有多個(gè)同樣的裝飾器,它會(huì)先執(zhí)行后面的
function logClass1(params:string){
    return function(target:any){
      console.log('類裝飾器1')
    }
}
function logClass2(params:string){
    return function(target:any){
      console.log('類裝飾器2')
    }
}
function logAttribute1(params?:string){
    return function(target:any,attrName:any){
      console.log('屬性裝飾器1')
    }
}
function logAttribute2(params?:string){
    return function(target:any,attrName:any){
      console.log('屬性裝飾器2')
    }
}
function logMethod1(params?:string){
    return function(target:any,attrName:any,desc:any){
      console.log('方法裝飾器1')
    }
}
function logMethod2(params?:string){
    return function(target:any,attrName:any,desc:any){
      console.log('方法裝飾器2')
    }
}
function logParams1(params?:string){
    return function(target:any,attrName:any,desc:any){
      console.log('方法參數(shù)裝飾器1')
    }
}
function logParams2(params?:string){
    return function(target:any,attrName:any,desc:any){
      console.log('方法參數(shù)裝飾器2')
    }
}

@logClass1('http://www.itying.com/api')
@logClass2('xxxx')
class HttpClient{
    @logAttribute1()
    @logAttribute2()
    public apiUrl:string | undefined;
    constructor(){
    }
    @logMethod1()
    @logMethod2()
    getData(){
        return true;
    }
    setData(@logParams1() attr1:any,@logParams2() attr2:any,){
    }
}
var http:any=new HttpClient();
image.png

- 報(bào)錯(cuò)

1、Element implicitly has an ‘a(chǎn)ny’ type because expression of type ‘string’ can’t be used to index type ‘{ name: string; age: number; }’.
No index signature with a parameter of type ‘string’ was found on type ‘{ name: string; age: number; }’.ts(7053)

// tsconfig.json
{
    "compilerOptions": {
        "suppressImplicitAnyIndexErrors": true,
        ...
    },
    ...
}

參考文件: TypeScript踩坑記錄
參考文件:JavaScript 和 TypeScript 交叉口 —— 類型定義文件(*.d.ts)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容