TS學(xué)習(xí)過(guò)程

一、TS文件運(yùn)行前的準(zhǔn)備

1.1、node的安裝

你可以到 Node.js 官網(wǎng)去下載 Node 進(jìn)行安裝(https://node.js.org),建議你下載LTS版本,也就是長(zhǎng)期支持版本。安裝的過(guò)程我就不演示了,這個(gè)過(guò)程就和安裝 QQ 一樣,沒(méi)有任何難度。
如果你已經(jīng)安裝了,可以打開命令行工具,然后使用node -v命令查看安裝的版本,但是一般還有一個(gè)命令需要檢測(cè)一下,就是npm -v,如果兩個(gè)命令都可以輸出版本號(hào),說(shuō)明你的 Node 安裝已經(jīng)沒(méi)有任何問(wèn)題了。

1.2、TS的安裝

npm install typescript -g

注意:mac在執(zhí)行這段命令的時(shí)候報(bào)錯(cuò)如下:

npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access

使用了sudo cnpm install typescript -g執(zhí)行就安裝成功了

1.3、ts-node 的安裝

npm install -g ts-node

報(bào)錯(cuò)的話就使用sudo cnpm install -g ts-node安裝

以上都安裝成功的話就可以開始寫代碼,運(yùn)行代碼啦~(ts-node demo.ts)

二、基礎(chǔ)靜態(tài)類型和對(duì)象類型

2.1、基礎(chǔ)靜態(tài)類型

基礎(chǔ)靜態(tài)類型非常簡(jiǎn)單,只要在聲明變量的后邊加一個(gè):號(hào),然后加上對(duì)應(yīng)的類型哦。比如下面的代碼,就是聲明了一個(gè)數(shù)字類型的變量,叫做count。

let count: number = 1;
//這是一個(gè)number類型的

null,undefinded,symbol,booleanvoid這些都是最常用的基礎(chǔ)數(shù)據(jù)類型

//any任意類型:在定義的時(shí)候沒(méi)有定義類型,則該變量就是any類型
let age:any='12',
age = '我愛(ài)你中國(guó)'
image.png

2.2、對(duì)象類型

  • 對(duì)象類型
const xiaoJieJie: {
  name: string,
  age: number,
} = {
  name: "大腳",
  age: 18,
};
console.log(xiaoJieJie.name);
  • 數(shù)組類型
const xiaoJieJies: String[] = ["謝大腳", "劉英", "小紅"];
  • 類類型
const dajiao: Person = new Person();
  • 函數(shù)類型
const jianXiaoJieJie: () => string = () => {
  return "大腳";
};
自定義對(duì)象類型
interface XiaoJieJie {
  uname: string;
  age: number;
}

const xiaohong: XiaoJieJie = {
  uname: "小紅",
  age: 18,
};

2.3、類型注解和類型推斷

  • 類型注解(type annotation)
let count: number;
count = 123;
//這段代碼就是類型注解,意思是顯示的告訴代碼,我們的count變量就是一個(gè)數(shù)字類型,這就叫做類型注解
  • 類型推斷(type inference)
let countInference = 123;
//這時(shí)候我并沒(méi)有顯示的告訴你變量countInference是一個(gè)數(shù)字類型,但是如果你把鼠標(biāo)放到變量上時(shí),你會(huì)發(fā)現(xiàn) TypeScript 自動(dòng)把變量注釋為了number(數(shù)字)類型,也就是說(shuō)它是有某種推斷能力的,通過(guò)你的代碼 TS 會(huì)自動(dòng)的去嘗試分析變量的類型。

注意:

  • 如果 TS 能夠自動(dòng)分析變量類型, 我們就什么也不需要做了
  • 如果 TS 無(wú)法分析變量類型的話, 我們就需要使用類型注解

三、函數(shù)

3.1、函數(shù)的參數(shù)以及返回值

  • 函數(shù)有返回值
//   參數(shù)要指定類型、返回值也要指定類型
function getTotal(one: number, two: number): number {
  return one + two;
}

const total = getTotal(1, 2);
  • 函數(shù)沒(méi)有返回值
//沒(méi)有返回值的函數(shù),我們就可以給他一個(gè)類型注解void,代表沒(méi)有任何返回值。
//如果這樣定義后,再加入任何返回值,程序都會(huì)報(bào)錯(cuò)。
function sayHello(): void {
  console.log("hello world");
}
  • never返回值類型
//如果一個(gè)函數(shù)是永遠(yuǎn)也執(zhí)行不完的,就可以定義返回值為never(執(zhí)行的時(shí)候,拋出了異常,這時(shí)候就無(wú)法執(zhí)行完了)
function errorFuntion(): never {
  throw new Error();
  console.log("Hello World");
}


//一直循環(huán),也是我們常說(shuō)的死循環(huán),這樣也運(yùn)行不完
function forNever(): never {
  while (true) {}
  console.log("Hello JSPang");
}
  • 函數(shù)參數(shù)為對(duì)象(解構(gòu))
//如果參數(shù)是對(duì)象---對(duì)象解構(gòu)
function add({ one, two }: { one: number, two: number }): number {
  return one + two;
}

const three = add({ one: 1, two: 2 });
//如果參數(shù)是對(duì)象,并且里邊只有一個(gè)屬性
function getNumber({ one }: { one: number }): number {
  return one;
}

const one = getNumber({ one: 1 });

四、數(shù)組

4.1、一般數(shù)組類型的定義

const numberArr = [1, 2, 3];
//如果你要顯示的注解,也非常簡(jiǎn)單,可以寫成下面的形式。
const numberArr: number[] = [1, 2, 3];
//如果你的數(shù)組各項(xiàng)是字符串,你就可以寫成這樣。
const stringArr: string[] = ["a", "b", "c"];
//也就是說(shuō)你可以定義任意類型的數(shù)組,比如是undefined。
const undefinedArr: undefined[] = [undefined, undefined];
//既有數(shù)字類型,又有字符串的時(shí)候
const arr: (number | string)[] = [1, "string", 2];

4.2、數(shù)組中對(duì)象類型的定義

const xiaoJieJies: { name: string, age: Number }[] = [
  { name: "劉英", age: 18 },
  { name: "謝大腳", age: 28 },
];

//上面的寫法太麻煩,修改后
type Lady = { name: string, age: Number };

const xiaoJieJies: Lady[] = [
  { name: "劉英", age: 18 },
  { name: "謝大腳", age: 28 },
];

//上述寫法在對(duì)象里再加入一個(gè)屬性,編譯器就會(huì)報(bào)錯(cuò),修改為用類來(lái)定義
class Madam {
  name: string;
  age: number;
}

const xiaoJieJies: Madam[] = [
  { name: "劉英", age: 18 },
  { name: "謝大腳", age: 28 },
];

4.3、元祖的使用和類型約束

  • 元祖的了解

可以把元組看成數(shù)組的一個(gè)加強(qiáng),它可以更好的控制或者說(shuō)規(guī)范里邊的類型

const xiaojiejie: (string | number)[] = ["dajiao", 28, "teacher"];
//調(diào)換數(shù)組中元素的位置,如下,ts不能檢測(cè)到問(wèn)題
const xiaojiejie: (string | number)[] = ["dajiao", "teacher", 28];
//這時(shí),需要元祖來(lái)加強(qiáng)
const xiaojiejie: [string, string, number] = ["dajiao", "teacher", 28];
//把數(shù)組中的每個(gè)元素類型的位置給固定住了,這就叫做元組。

五、TypeScript 中的 interface 接口

5.1、interface接口的理解和使用

個(gè)人理解: 從js的角度看ts中的interface,就是先聲明了一個(gè)對(duì)象obj,這個(gè)對(duì)象obj里面有很多的屬性name,這個(gè)對(duì)象obj會(huì)在你后面定義的方法fun中當(dāng)作參數(shù)(形參)傳進(jìn)去,這個(gè)對(duì)象obj中的屬性有必傳的、非必傳的、還有函數(shù)類型的。你在方法fun中若要使用某個(gè)屬性name,那么這個(gè)屬性name需要在對(duì)象obj中定義過(guò),否則會(huì)報(bào)錯(cuò)。(除非interface中定義了[propname: string]: any;屬性)
注意:對(duì)象中的每一個(gè)屬性都需要定義類型,方法定義返回值的類型

// 這是定義的一個(gè)obj
interface Girl {
    // 每一個(gè)屬性都要有類型
    name: string;
    age: number;
    // 必傳的屬性
    height: number;
    // 非必傳的屬性
    footer?: number;
    // 允許加入任意值 
    // 在實(shí)參中新增了sex屬性,interface中并沒(méi)有定義,此時(shí)并沒(méi)有報(bào)錯(cuò)
    [propname: string]: any;
    // 存方法,要定義返回值的類型
    say(): string;
    //非必傳方法
    run?(): void;
}
// 后面定義的方法 fun 把上面定義的對(duì)象 Girl 當(dāng)作參數(shù)傳給方法
const screenResume = (girl: Girl) => {
    girl.age < 24 && girl.height >= 168 && console.log(girl.name + "進(jìn)入面試");
    girl.age > 24 || (girl.height < 168 && console.log(girl.name + "你被淘汰"));
  };
  
  const getResume = (girl: Girl) => {
    console.log(girl.name + "年齡是:" + girl.age);
    console.log(girl.name + "身高是:" + girl.height + "cm");
    girl.footer  &&  console.log(girl.name + "鞋碼是:" + girl.footer + "碼");
    girl.sex && console.log(girl.name + "性別是:" + girl.sex);
    console.log(girl.name + "開心說(shuō):" + girl.say());
  };
  //實(shí)參
  const girl = {
    name: "大腳",
    age: 18,
    height: 174,
    footer: 38,
    // 這里不報(bào)錯(cuò)的原因是 interface中增加了 [propname: string]: any;屬性
    sex: '女',
    say() {
        return "hello world";
      },    
  };
  //調(diào)用方法
  screenResume(girl);
  getResume(girl);

控制臺(tái)輸出的內(nèi)容:

大腳進(jìn)入面試
大腳年齡是:18
大腳身高是:174cm
大腳鞋碼是:38碼
大腳性別是:女
大腳開心說(shuō):hello world

5.2 implements --- 接口(interface)的引用(被class引用)

// implements 是指 類 引用了 某個(gè) 接口(interface)
//這里是指 XiaoJieJie這個(gè)類 引用了 Girl 這個(gè)接口,此時(shí)定義XiaoJieJie這個(gè)類的時(shí)候,要給必傳屬性賦值
class XiaoJieJie implements Girl {
    name = '小花';
    age = 18;
    height = 180;
    say() {
        return "傻子"
    }
}
//new XiaoJieJie() ----實(shí)例對(duì)象
screenResume(new XiaoJieJie())
getResume(new XiaoJieJie())

控制臺(tái)輸出的結(jié)果:

小花進(jìn)入面試
小花年齡是:18
小花身高是:180cm
小花開心說(shuō):傻子

5.3、extends --- 接口的繼承

// extends 是指 新的接口 繼承了 某個(gè)接口
interface Boy extends Girl {
    play(): string;
}
const boy = {
    name: 'wanwan',
    age: 18,
    height: 185,
    say() {
        return "是你呀";
    },
    play() {
        return "打籃球";
    } 
}

const getResume = (girl: Boy) => {
    console.log(girl.name + "年齡是:" + girl.age);
    console.log(girl.name + "身高是:" + girl.height + "cm");
    girl.footer  && console.log(girl.name + "鞋碼是:" + girl.footer + "碼");
    girl.sex && console.log(girl.name + "性別是:" + girl.sex);
    girl.say() && console.log(girl.name + "開心說(shuō):" + girl.say());
    girl.play() && console.log(girl.name + "喜歡的運(yùn)動(dòng)是:" + girl.play());
};
getResume(boy);

控制臺(tái)結(jié)果:

wanwan年齡是:18
wanwan身高是:185cm
wanwan開心說(shuō):是你呀
wanwan喜歡的運(yùn)動(dòng)是:打籃球

5.4、函數(shù)型接口

因?yàn)閷?duì)象中僅包含一個(gè)函數(shù),這個(gè)對(duì)象的全部意義也僅在于那個(gè)可被外部調(diào)用的函數(shù),故而稱之為函數(shù)型接口。

六、TypeScript 中類的概念和使用

6.1、類的概念

使用關(guān)鍵字 class

// 定義一個(gè)類
class Lady {
    content = "Hi,帥哥";
    sayHello() {
        return this.content;
    }
}
// 實(shí)例類的對(duì)象
const goddess = new Lady();
console.log(goddess.sayHello());

6.2、extends --- 類的繼承

// 定義一個(gè)類
class Lady {
    content = "Hi,帥哥";
    sayHello() {
        return this.content;
    }
}
// XiaoJieJie類身上既有自己的方法,也有從Lady類繼承來(lái)的方法
class XiaoJieJie extends Lady {
    sayLove() {
        return "I love you";
    }
}

console.log(new XiaoJieJie().sayHello());//Hi,帥哥
console.log(new XiaoJieJie().sayLove());//I love you

6.3、類(繼承的子類)的重寫和super關(guān)鍵字

// 定義一個(gè)類
class Lady {
    content = "Hi,帥哥";
    sayHello() {
        return this.content;
    }
}
// XiaoJieJie類身上既有自己的方法,也有從Lady類繼承來(lái)的方法
class XiaoJieJie extends Lady {
    sayLove() {
        return "I love you";
    }
    // 可以對(duì)繼承來(lái)的方法進(jìn)行重寫
    sayHello() {
        return "hi, wan";
    }
    // 繼續(xù)使用Lady中的方法
    ladySayHello() {
        return super.sayHello() + "。你好!";
    }
}

console.log(new XiaoJieJie().sayHello());//hi, wan
console.log(new XiaoJieJie().sayLove());//I love you
console.log(new XiaoJieJie().ladySayHello());//Hi,帥哥。你好!

6.4、類的訪問(wèn)類型 --- private、protected、public

  • public

public從英文字面的解釋就是公共的或者說(shuō)是公眾的,在程序里的意思就是允許在類的內(nèi)部和外部被調(diào)用.

  • private

private 訪問(wèn)屬性的意思是,只允許再類的內(nèi)部被調(diào)用,外部不允許調(diào)用

  • protected

protected 允許在類內(nèi)及繼承的子類中使用

class Person {
    protected name:string;
    private age: number;
    public sayHello(){
        // 在類中使用 private 和 protected 屬性都不會(huì)報(bào)錯(cuò)
        console.log(this.name + 'say Hello' + ",年齡是:" + this.age)  //此處不報(bào)錯(cuò)
    }
}
//-------以下屬于類的外部--------
const person = new Person()
//此處報(bào)錯(cuò)---屬性“name”受保護(hù)(protected),只能在類“Person”及其子類中訪問(wèn)。
person.name = 'jspang.com'
//此處報(bào)錯(cuò)---屬性“age”為私有屬性(private),只能在類“Person”中訪問(wèn)。
person.age = 12 
person.sayHello()
//此處報(bào)錯(cuò)---屬性“name”受保護(hù),只能在類“Person”及其子類中訪問(wèn)。
console.log(person.name)  
image.png

6.5、類的構(gòu)造函數(shù)

  • 1、通過(guò)構(gòu)造函數(shù)給類增加屬性

類的構(gòu)造方法只在實(shí)例化的時(shí)候被調(diào)用,并且只調(diào)用一次。
類的構(gòu)造方法在類的外部無(wú)法訪問(wèn)。

  • 2、調(diào)用構(gòu)造方法中定義的屬性
  • 3、構(gòu)造函數(shù)的訪問(wèn)控制符
class Person{
    // 在構(gòu)造函數(shù)中定義屬性,必須給屬性添加訪問(wèn)控制符(訪問(wèn)類型)
    constructor(public name: string){
        this.name = name
        console.log(this.name);
    };
    public sayHello(){
        // 這里的name需要通過(guò)this.name去獲取,直接寫name獲取不到
        console.log(this.name+':hello world')
    }
}
let girl = new Person("xiaohua");//xiaohua(實(shí)例化的時(shí)候構(gòu)造函數(shù)被調(diào)用)
// 調(diào)用構(gòu)造方法中定義的屬性
girl.sayHello();//xiaohua:hello world
console.log(girl.name); //xiaohua

6.5、繼承類的構(gòu)造器寫法

子類中使用構(gòu)造函數(shù)需要用super()調(diào)用父類的構(gòu)造函數(shù)

// 父類
class Person{
    // 在構(gòu)造函數(shù)中定義屬性,必須給屬性添加訪問(wèn)控制符(訪問(wèn)類型)
    constructor(public name: string){
        this.name = name
        console.log(this.name);
    };
    public sayHello(){
        // 這里的name需要通過(guò)this.name去獲取,直接寫name獲取不到
        console.log(this.name+':hello world')
    }
}
// 子類
class Teacher extends Person{
    constructor(public age: number){
        // 若父類的構(gòu)造函數(shù)有參數(shù)則子類在使用super()時(shí)也需要傳遞參數(shù)否則會(huì)報(bào)錯(cuò)(2)
        // 1、未寫super時(shí)報(bào)錯(cuò)---派生類的構(gòu)造函數(shù)必須包含 "super" 調(diào)用
        // 2、未寫參數(shù)時(shí)報(bào)錯(cuò)---應(yīng)有 1 個(gè)參數(shù),但獲得 0 個(gè);未提供 "name" 的自變量。
        super("小花")
        // 若父類的構(gòu)造函數(shù)沒(méi)有參數(shù)則子類在使用super()時(shí)不需要傳參數(shù)
        this.age = age;
        console.log(this.name + "今年" + this.age + "歲")
    }
}
let girl = new Person("xiaohua");//xiaohua(實(shí)例化的時(shí)候構(gòu)造函數(shù)被調(diào)用)
// 調(diào)用構(gòu)造方法中定義的屬性
girl.sayHello();//xiaohua:hello world
console.log(girl.name); //xiaohua

let teach = new Teacher(24);//小花今年24歲(實(shí)例化的時(shí)候構(gòu)造函數(shù)被調(diào)用)

6.6、類的 getter 、 setter 、static

  • getter 、 setter

getter和setter都是屬性,用get()和set()來(lái)設(shè)置private類型的屬性可修改和獲取

// set和get方法---用來(lái)修改private屬性的值
class Person {
    private _name: string;
    constructor(private _age: number) {
        console.log(this._name + "今年" + this._age + "歲")
    }
    get name() {
        return this._name
    }
    set name(value) {
        this._name = value
    }
    get age() {
        return this._age - 10
    }
    set age(age: number) {
        this._age = age
    }
}
const girl = new Person(18)//undefined今年18歲
girl.name = "小花"
girl.age = 23
console.log(girl.name + "今年" + girl.age + "歲")//小花今年13歲
  • 類中的static

當(dāng)你不想new出對(duì)象,而想直接使用這個(gè)方法,用static聲明的屬性和方法,不需要進(jìn)行聲明對(duì)象,就可以直接使用

readonly只讀屬性

class Person {
    public static logo: String = "huahua";
    // readonly只讀屬性
    public readonly xingm: string;
    static sayLove() {
        return "I Love you " + this.logo;
    }
}
new Person().xingm = 'www';//報(bào)錯(cuò) --- 無(wú)法分配到 "xingm" ,因?yàn)樗侵蛔x屬性。
console.log(Person.sayLove());//I Love you huahua
  • 抽象類---abstract

抽象類--- 用abstract 修飾, 里面可以沒(méi)有抽象方法。但有抽象方法(abstract method)的類必須聲明為抽象類(abstract class)

abstract class Development {
    //抽象方法 ,不包含具體實(shí)現(xiàn),要求子類中必須實(shí)現(xiàn)此方法
    abstract skill():any;
    //非抽象方法,無(wú)需要求子類實(shí)現(xiàn)、重寫
    equipment(){
        console.log('非抽象方法,不要子類實(shí)現(xiàn)、重寫');
    }

}
// 多態(tài):父類定義一個(gè)方法不去實(shí)現(xiàn),讓繼承它的子類去實(shí)現(xiàn) 每一個(gè)子類有不同的表現(xiàn)
// 注意:使用多態(tài)基礎(chǔ)是類的繼承或者接口實(shí)現(xiàn)
class Frontend extends Development {
     //子類中必須實(shí)現(xiàn)父類抽象方法,否則ts編譯報(bào)錯(cuò)
    skill() {
        console.log("我是一個(gè)前端")
    }
}
class Backend extends Development {
    skill() {
        console.log("我是一個(gè)后端")
    }
}
class UI extends Development {
    skill() {
        console.log("我是一個(gè)UI")
    }
}

七、聯(lián)合類型和類型保護(hù)

  • 1、聯(lián)合類型(Union Types)可以通過(guò)管道(|)將變量設(shè)置多種類型,賦值時(shí)可以根據(jù)設(shè)置的類型來(lái)賦值。
  • 2、類型保護(hù)

1、類型斷言就是通過(guò)斷言的方式確定傳遞過(guò)來(lái)的準(zhǔn)確值(傳遞過(guò)來(lái)的值中是否存在某個(gè)準(zhǔn)確的值)
2、in語(yǔ)法
3、typeof語(yǔ)法
4、instanceof語(yǔ)法(只能用在類上)

個(gè)人:這一段理解比較重要,不知道怎么描述

八、枚舉

使用枚舉我們可以定義一些帶名字的常量。 使用枚舉可以清晰地表達(dá)意圖或創(chuàng)建一組有區(qū)別的用例。 TypeScript支持?jǐn)?shù)字的和基于字符串的枚舉。

// 隨機(jī)選擇一個(gè)數(shù)字
// function getServe(status: number) {
//     if (status === 0) {
//         return "這是0";
//     } else if (status === 1) {
//         return "這是1";
//     } else if (status === 2) {
//         return "這是2";
//     }else if (status === 3) {
//         return "這是3";
//     }
// }
// const result = getServe(2);
// console.log(`輸出:${result}`);


// const Stauts = {
//     ZERO: 0,
//     ONE: 1,
//     TWO: 2,
// };
// function getServe(status: any) {
//     if (status === Stauts.ZERO) {
//         return "這是0";
//     } else if (status === Stauts.ONE) {
//         return "這是1";
//     } else if (status === Stauts.TWO) {
//         return "這是2";
//     }
// }
// const result = getServe(Stauts.ONE);
// console.log(`輸出:${result}`);

enum Stauts {
    ZERO,
    ONE,
    TWO,
};
function getServe(status: any) {
    if (status === Stauts.ZERO) {
        return "這是0";
    } else if (status === Stauts.ONE) {
        return "這是1";
    } else if (status === Stauts.TWO) {
        return "這是2";
    }
}
// const result = getServe(Stauts.TWO);//輸出:這是2
const result = getServe(2);//輸出:這是2
console.log(`輸出:${result}`);
console.log(Stauts.TWO, Stauts[2]);//2 TWO

九、泛型

泛型:[generic - 通用、泛指的意思],那最簡(jiǎn)單的理解,泛型就是泛指的類型。
泛型的本質(zhì)是參數(shù)化類型,通俗的將就是所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù),這種參數(shù)類型可以用在類、接口和方法的創(chuàng)建中,分別成為泛型類,泛型接口、泛型方法。
泛型的定義使用<>(尖角號(hào))進(jìn)行定義

9.1、泛型的使用

// identity函數(shù)。 這個(gè)函數(shù)會(huì)返回任何傳入它的值
// function identity(arg: number): number {
//     return arg;
// }
// 這時(shí)identity函數(shù)就不可以傳除number類型以外類型的參數(shù)
// console.log(identity(1))

// function identity(arg: any): any {
//     return arg;
// }
// // 使用any類型會(huì)導(dǎo)致這個(gè)函數(shù)可以接收任何類型的arg參數(shù),
// // 這樣就丟失了一些信息:傳入的類型與返回的類型應(yīng)該是相同的(要自己typeof才會(huì)知道)
// console.log(identity(111))

// 泛型的使用
function identity<T>(arg: T): T {
    return arg;
}
console.log(identity(111))

//STR:兩個(gè)參數(shù)的類型相同
function join<STR>(first: STR, second: STR) {
    return `${first}${second}`;
}
// 參數(shù)的類型可以在調(diào)用的時(shí)候定義
console.log(join<string>("我是", "huahua"))//我是huahua
console.log(join<number>(1,2))//12

9.2、泛型中數(shù)組的使用

// 泛型中 數(shù)組的使用
// 泛型函數(shù)loggingIdentity,接收類型參數(shù)T和參數(shù)arg,它是個(gè)元素類型是T的數(shù)組,并返回元素類型是T的數(shù)組
// 第一種寫法
// function loggingIdentity<T>(agr: T[]){
//     console.log(agr.length)
// }
// loggingIdentity<number>([1,2,3])
// 第二種寫法
// function loggingIdentity<T>(agr: Array<T>){
//     console.log(agr.length)
// }
// loggingIdentity<number>([1,2,3])

9.3、多個(gè)泛型的定義

// 多個(gè)泛型的定義
function joinMore<T, P>(first: T, second: P) {
    return `${first}${second}`;
}
joinMore<number, string>(1, "2");
// 注意:如果函數(shù)定義了多個(gè)泛型,使用時(shí)要對(duì)應(yīng)的定義出具體的類型。

9.4、泛型類

// class Person {
//     constructor(private girls: string[]) {}
//     getGirl(index: number): string {
//         return this.girls[index]
//     }
// }
// const girls = new Person(["huahua", "dahua", "xiaohua"]);
// console.log(girls.getGirl(1));//dahua

//此時(shí)若需要傳入的數(shù)組是number類型的,上述代碼則不能正常運(yùn)行,此時(shí)使用泛型

class Person<T> {
    constructor(private girls: T[]) {}
    getGirl(index: number): T {
        return this.girls[index]
    }
}
const girls = new Person<string>(["huahua", "dahua", "xiaohua"]);
const boys = new Person<number>([1,2,3])
console.log(girls.getGirl(1));//dahua
console.log(boys.getGirl(1));//2

泛型類(好理解的方式---類的復(fù)用)

class GetMin<T>{
    arr: T[] = [];
    add(ele: T) {
        this.arr.push(ele);
    }
    min(): T {
        var min = this.arr[0];
        this.arr.forEach(function (value) {
            if (value < min) {
                min = value;
            }
        });
        return min;
    }
}
var gm1 = new GetMin<number>();
gm1.add(5);
gm1.add(3);
gm1.add(2);
gm1.add(9);
console.log(gm1.min());
//比較字符在字母表中的索引
var gm2 = new GetMin<string>();
gm2.add("tom");
gm2.add("jerry");
gm2.add("jack");
gm2.add("sunny");
console.log(gm2.min());

9.5、泛型中類的繼承

  • 先看泛型中類的寫法
class Person<T> {
    constructor(private girls: T[]) {}
    getGirl(index: number): T {
        return this.girls[index]
    }
}
const girls = new Person<string>(["huahua", "dahua", "xiaohua"]);
console.log(girls.getGirl(1));//dahua

上述寫法中,getGirl方法只是獲取了這個(gè)數(shù)組的第幾項(xiàng),在實(shí)際開發(fā)過(guò)程中,我們數(shù)組的每一項(xiàng)一般都是對(duì)象,const girls = new Person([ { name: "huahua" }, { name: "dahua" }, { name: "xiaohua" }, ]);此時(shí)需要獲取這個(gè)對(duì)象的屬性值(name),此時(shí)getGirl()的return就需要是this.girls[index].name,但是此時(shí)會(huì)報(bào)錯(cuò)

image.png
此時(shí),我們可以寫一個(gè)接口(含有name屬性),讓類Person繼承這個(gè)接口

interface Girl {
    name: string
}
class Person<T extends Girl> {
    constructor(private girls: T[]) { }
    getGirl(index: number): string {
        return this.girls[index].name
    }
}
const girls = new Person([
    { name: "huahua" },
    { name: "dahua" },
    { name: "xiaohua" },
]);
console.log(girls.getGirl(1));//dahua

9.6、泛型的約束

可以使用關(guān)鍵字extends來(lái)進(jìn)行約束

class Person<T extends number | string> {
  //.....
}

十、實(shí)際開發(fā)

自己百度吧,整理太麻煩

以上參考: https://jspang.com/detailed?id=63#toc290

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。