一、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
,boolean
,void
這些都是最常用的基礎(chǔ)數(shù)據(jù)類型
//any任意類型:在定義的時(shí)候沒(méi)有定義類型,則該變量就是any類型
let age:any='12',
age = '我愛(ài)你中國(guó)'
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)
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ò)
此時(shí),我們可以寫一個(gè)接口(含有name屬性),讓類image.pngPerson
繼承這個(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