Vue3 TypeScript 快速上手手冊(cè)_第1頁
Vue3 TypeScript 快速上手手冊(cè)_第2頁
Vue3 TypeScript 快速上手手冊(cè)_第3頁
Vue3 TypeScript 快速上手手冊(cè)_第4頁
Vue3 TypeScript 快速上手手冊(cè)_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Vue3+TypeScript?看這一篇就夠了

1、Typescript快速上手

1.1初識(shí)TypeScript

Typescript

StronglyTyped

TypeScript的介紹

TypeScript是一種由微軟開發(fā)的開源、跨平臺(tái)的編程語言。它是JavaScript的超集,最終會(huì)被編譯為JavaScript代碼,

2012年10月,微軟發(fā)布了首個(gè)公開版本的TypeScript,2013年6月19日,在經(jīng)歷了一個(gè)預(yù)覽版之后微軟正式發(fā)布了正式版

TypeScriptTypeScript的作者是安德斯?海爾斯伯格,C#的首席架構(gòu)師.它是開源和跨平臺(tái)的編程語言.

TypeScript擴(kuò)展了JavaScript的語法,所以任何現(xiàn)有的JavaScript程序可以運(yùn)行在TypeScript環(huán)境中。

TypeScript是為大型應(yīng)用的開發(fā)而設(shè)計(jì),并且可以編譯為JavaScript。

TypeScript是JavaScript的一個(gè)超集,主要提供了類型系統(tǒng)和對(duì)ES6+的支持*"它由Microsoft開發(fā),代碼開源于GitHub上

TypeScript是JavaScript的一個(gè)超集,主要提供了類型系統(tǒng)和對(duì)ES6+的支持,它由Microsoft開發(fā),代碼上

TypeScript的特點(diǎn)

TypeScript主要有3大特點(diǎn):

-始于JavaScript,歸于JavaScript

TypeScript可以編譯出純凈、簡(jiǎn)潔的JavaScript代碼,并且可以運(yùn)行在任何瀏覽器上、Node.js環(huán)境中和任何支持ECMAScript3(

或更高版本)的JavaScript引擎中.

?強(qiáng)大的類型系統(tǒng)

類型系統(tǒng)允許JavaScript開發(fā)者在開發(fā)JavaScript應(yīng)用程序時(shí)使用高效的開發(fā)工具和常用操作比如靜態(tài)檢查和代碼重構(gòu).

?先進(jìn)的JavaScript

TypeScript提供最新的和不斷發(fā)展的JavaScript特性,包括那些來自2015年的ECMAScript和未來的提案中的特性,比如異步功能

和Decorators,以幫助建立健壯的組件.

總結(jié)

Typescript在社區(qū)的流行度越來越高,它非常適用于一些大型項(xiàng)目,也非常適用于一些基礎(chǔ)庫,極大地幫助我們提升了開發(fā)效率和體驗(yàn).

1.2安裝Typescript

命令行運(yùn)行如下命令,全局安裝Typescript:

npminstall-gtypescript

安裝完成后,在控制臺(tái)運(yùn)行如下命令,檢杳安裝是否成功(3.x):

tsc-V

1.3.第一個(gè)TypeScript

編寫TS程序

src/helloworld,ts

functiongreeteriperson){

return'Hello,'+person

}

letuser='Yee'

consoie.iog(greeter(user)

手動(dòng)編譯代碼

我們使用了.ts擴(kuò)展名,但是這段代碼僅僅是JavaScript而已。

在命令行上,運(yùn)行TypeScript編譯器:

tschelloworld.ts

輸出結(jié)果為一個(gè)helloworld.js文件,它包含了和輸入文件中相同的JavsScript代碼.

在命令行上,通過Node.js運(yùn)行這段代碼:

nodehelloworld.js

控制臺(tái)輸出:

Hello,Yee

VsCode自動(dòng)編譯

1).生成配省文件tsconfig.json

tsc-init

2).修改stconfig.json配置

"outDir"

"strict":false,

3).啟動(dòng)監(jiān)視任務(wù):

終端->運(yùn)行任務(wù)->監(jiān)視tsconfig.json

類型注解

接下來讓我們看看TypeScript工具帶來的高級(jí)功能.給person函數(shù)的參數(shù)添加:string類型注解,如下:

functiongreeter(person:string){

return'Hello,'+person

letuser='Yee'

console.log(greeteruser)

Typescript里的類型注解是一種輕量級(jí)的為函數(shù)或變量添加約束的方式.在這個(gè)例子里,我們希望greeter函數(shù)接收一個(gè)字符串參數(shù)。

然后嘗試把greeter的調(diào)用改成傳入一個(gè)數(shù)組:

functiongreeter(personstring){

return'Hello,'+person

)

letuser=[0.1,2]

console.log(greeter(user)

重新編譯,你會(huì)看到產(chǎn)生了一個(gè)錯(cuò)誤:

errorTS2345:Argumentoftype'number。'isnotassignabletoparameteroftype'string'.

類似地,嘗試刪除greeter調(diào)用的所有參數(shù).TypeScript會(huì)告訴你使用了非期望個(gè)數(shù)的參數(shù)調(diào)用了這個(gè)函數(shù)。在這兩種情

況中,Typescript提供了靜態(tài)的代碼分析,它可以分析代碼結(jié)構(gòu)和提供的類型注解。

要注意的是盡管有錯(cuò)誤,greeterJs文件還是被創(chuàng)建了.就算你的代碼里有錯(cuò)誤,你仍然可以使用TypeScript.但在這種情況

下,Typescript會(huì)警告你代碼可能不會(huì)按預(yù)期執(zhí)行.

接口

讓我們繼續(xù)擴(kuò)展這個(gè)示例應(yīng)用.這里我們使用接口來描述一個(gè)擁有firstName和lastName字段的對(duì)象.在TypeScript里,只在兩個(gè)類

型內(nèi)部的結(jié)構(gòu)兼容,那么這兩個(gè)類型就是兼容的.這就允許我們?cè)趯?shí)現(xiàn)接口時(shí)候只要保證包含了接口要求的結(jié)構(gòu)就可以,而不必明確地

使用implements語句。

interfacePerson{

firstName:string

lastNamestring

)

functiongreeter(personPerson{

return'Hello,'+personfirstName+''+personlastName

}

letuser={

firstName:'Yee',

lastName:'Huang'

)

console.log(oreeter(user))

最后,讓我們使用類來改寫這個(gè)例子.TypeScript支持JavaScript的新特性,比如支持基于類的面向?qū)ο缶幊獭?/p>

讓我們創(chuàng)建一個(gè)User類,它帶有一個(gè)構(gòu)造函數(shù)和一些公共字段.因?yàn)轭惖淖侄伟私涌谒枰淖侄?所以他們能很好的兼容。

還要注意的是,我在類的聲明上會(huì)注明所有的成員變量,這樣比較一目了然。

classUser|

fullNamestring

firstName:string

laslNanie:siring

constructor(firstName:string,lastNamestring){

thisfirstName=firstName

thislasthame=lastName

thisfullName=firstName+"+lastName

}

}

interfacePerson{

firstName:string

lastName:string

}

functiongreeteripersonPerson{

return'Hello,'+personfirstName+''+personlastName

)

letuser=newUserYee','Huang')

console.log(greeter(user)

重新運(yùn)行tscgreeter.ts,你會(huì)看到TypeScript里的類只是一個(gè)語法糖,本質(zhì)上還是JavaScript函數(shù)的實(shí)現(xiàn)。

總結(jié)

到這里,你已經(jīng)對(duì)Typescript有了一個(gè)大致的印象,那么下一章讓我們來一起學(xué)習(xí)TypeScript的一些常用語法吧。

1.4使用webpack打包TS

下載依賴

yarnadd-Dtypescript

yarnadd-Dwebpackwebpack-cli

yarnadd-Dwebpack-dev-server

yarnadd-Dhtml-webpack-pluginclean-webpack-plugin

yarnadd-Dts-loader

yarnadd-Dcross-env

入口JS:src/main.ts

/import'./01_helloworld'

documentwrtte('HelloWebpackTS!')

index頁面:public/index.html

<!DOCTYPEhtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"content="width=device-width,initial-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title:webpack&TStitle>

</head>

<body>

<.body>

const{CleanWebpackPlugin:requireCclean-webpack-plugin")

constHtmlWebpackPlugin=require('html-webpack-plugin')

constpath=require('path')

constisProd=processenv.NODE_ENV==='production'

functionresolve(dir){

returnpathresolvetdirname'dir)

}

moduleexports-{

modeisProd?'production':'development'.

entry:{

app'Jsrcmain.ts'

},

output:{

pathresolve('dist'),

filename[name].[contenthash:8].js'

},

module{

rules[

(

testA.tsx?$/,

use'ts-loader',

include:[resolveCsrc')]

}

]

},

plugins[

newCleanWebpackPlugin({

}),

newHtmlWebpackPlugin

template:'.public'index.html'

))

].

resolve{

extensions(*.ts','.tsx','jsl

},

devtoolisProd?'cheap-module-source-map':'cheap-module-eval-source-map',

devServer{

host'localhost*,/主機(jī)名

stats:,errors-only'J打包R志輸出輸出錯(cuò)誤侑息

port8081.

opentrue

},

}

配置打包命令

"dev":ucross-envNODE_ENV=developmentwebpack-dev-server-configbuild/webpack.config.js",

"build":"cross-envNODE_ENV=productionwebpack-configbuild'webpack.config.js"

運(yùn)行與打包

2、Typescript常用語法

2.1基礎(chǔ)類型

Typescript支持與JavaScript幾乎相同的數(shù)據(jù)類型,此外還提供了實(shí)用的枚舉類型方便我們使用。

布爾值

最基本的數(shù)據(jù)類型就是簡(jiǎn)單的true/false值,在JavaScript和TypeScript里叫做boolean(其它語言中也一樣).

letisDoneboolean=false;

isDone=true:

/isDone=2/error

數(shù)字

和JavaScript一樣,TypeScript里的所有數(shù)字都是浮點(diǎn)數(shù)。這些浮點(diǎn)數(shù)的類型是number,除了支持十進(jìn)制和十六進(jìn)制字

面量,TypeScript還支持ECMAScript2015中引入的二進(jìn)制和八進(jìn)制字面量.

leta1:number=10升迸制

leta2:number=Ob1010二進(jìn)制

leta3:number=Oo12,八進(jìn)制

leta4:number=Oxa"六進(jìn)制

字符串

JavaScript程序的另一項(xiàng)基本操作是處理網(wǎng)頁或服務(wù)器端的文本數(shù)據(jù).像其它語言里一樣,我們使用string表示文本數(shù)據(jù)類型.

和JavaScript一樣,可以使用雙引號(hào)(")或單引號(hào)(*)表示字符串。

letnamestring='tom'

name:'jack'

/name=12/error

letagenumber=12

constinfo=Mynameis${name;,Iam${age}yearsold!'

undefined和null

TypeScript里,undefined和null兩者各自有自己的類型分別叫做undefined和null.它們的本身的類型用處不是很大:

letuundefined:undefined

letn:null=null

默認(rèn)情況下null和undefined是所有類型的子類型。就是說你可以把null和undefined賦值給number類型的變量.

數(shù)組

TypeScript像JavaScript一樣可以操作數(shù)組元素.有兩種方式可以定義數(shù)組。第一種,可以在元素類型后面接上[],表示由此類型元素

組成的一個(gè)數(shù)組:

letlistlnumber口=[1,2,3]

第二種方式是使用數(shù)組泛型,Arrayv元素類型〉:

letIlst2Array<number>=[1,2.3]

元組Tuple

元組類型允許表示一個(gè)已知元素?cái)?shù)量和類型的數(shù)組,各元素的類型不必相同。比如,你可以定義一對(duì)值分別為string和number類型的

元組。

lettl:[string,number]

t1=['hello',10]/OK

t1=[10,'hello']/Error

當(dāng)訪問一個(gè)已知索引的元素,會(huì)得到正確的類型:

console.log(t1[0].substring(1))/OK

console.log(tl[l].substring(l))/Error,number^^±'substring

枚舉

enum類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充。使用枚舉類型可以為一組數(shù)值賦予友好的名字。

enumColor{

Red

Green.

Blue

)

故舉效值默認(rèn)從。開始依次遞熠

,根據(jù)特定的名稱得到對(duì)應(yīng)的枚舉數(shù)值

letmyColorColor=ColorGreen/0

console.logmyColorColorRedColorBlue

默認(rèn)情況下,從0開始為元素編號(hào),你也可以手動(dòng)的指定成員的數(shù)值。例如,我們將上面的例子改成從1開始編號(hào):

enumColorRed=1GreenBlue}

letcColor=ColorGreen

或者,全部都采用手動(dòng)賦值:

enumColorRed=1Green=2Blue=4}

letcColor=ColorGreen

枚舉類型提供的一個(gè)便利是你可以由枚舉的值得到它的名字。例如,我們知道數(shù)值為2,但是不確定它映射到Color里的哪個(gè)名字,我們

可以查找相應(yīng)的名字:

enumColorRed=1GreenBlue;

letcolorName:string=Color2|

console.log(colorName)/'Green'

any

有時(shí)候,我們會(huì)想要為那些在編程階段還不清楚類型的變量指定一個(gè)類型.這些隹可能來自于動(dòng)態(tài)的內(nèi)容,比如來自用戶輸入或第三方代

碼庫。這種情況下,我們不希望類型檢查器對(duì)這些值進(jìn)行檢瓷而是直接讓它們通過編譯階段的檢查。那么我們可以使用any類型來標(biāo)記這

些變量:

letnotSureany=4

notSure='maybeastring'

notSure=false/也可以是個(gè)boolean

在對(duì)現(xiàn)有代碼進(jìn)行改寫的時(shí)候,any類型是十分自用的,它允出爾在編譯時(shí)可選擇地包含或移除類型檢直。井且當(dāng)你只知道一部分?jǐn)?shù)據(jù)的

類型時(shí),any類型也是有用的。比如,你有一個(gè)數(shù)組,它包含了不同的類型的

letlistanyO=[1,true,'free']

list[1]=1OO

void

某種程^上來說,void類型像是與any類型相反,它表示沒有任何類型.當(dāng)一個(gè)函數(shù)沒有返回值時(shí),你通常會(huì)見到其返回值類型是void

「痂■沒有任何類型,一雌來說明,勺返回值不能是undefined和null之夕版值*/

functionfn(i:void{

console.log('fn()')

/returnundefined

/returnnull

/return1/error

)

聲明一個(gè)void類型的變量沒有什么大用,因?yàn)槟阒荒転樗x予undefined和null:

letunusable:void=undefined

object

object表示非原始類型,也就是除number,string,boolean之夕曲類型。

使用object類型,就可以更好的表示像Object.create這樣的API.例如:

functionfn2(objobject):object

console.log('fn20'.obji

return{}

/returnundefined

/returnnull

)

console.log(fn2(newStringabc')))

/console.log(fn2('abc')/error

console.log(tn2String))

聯(lián)合類型

聯(lián)合類型(UnionTypes)表示取值可以為多種類型中的一種

需求1:定義一個(gè)一個(gè)函數(shù)得到一個(gè)數(shù)字或字符串值的字符串形式值

functiontoString2(x:number|string):string{

returnxtoString()

)

需求2:定義一個(gè)一個(gè)函數(shù)得到一個(gè)數(shù)字或字符串值的長(zhǎng)度

functiongetLength(x:number)string){

/returnx.length/error

if(xlength){/error

returnxlength

}else{

returnx.toString()length

}

}

類型斷言

通過類型斷言這種方式可以告訴編譯器,"相信我,我知道自己在干什么”.類型斷言好比其它語言里的類型轉(zhuǎn)換,但是不進(jìn)行特殊的

數(shù)據(jù)檢量懈構(gòu)。它沒有運(yùn)行時(shí)的影響,只是在編譯階段起作用。Typescript會(huì)假設(shè)你,程序員,已經(jīng)進(jìn)行了必須的檢查。

類型斷言有兩種形式。其一是“尖括號(hào)”語法,另一個(gè)為as語法

/,

贊雌(TypeAssertion):可以再痔動(dòng)指定一個(gè)值的類型

語.式一:<類型〉值

方式二:道as類型tsx中只能用這種方式

*/

r需求:定L個(gè)函數(shù)得到-個(gè)字符串或者數(shù)值數(shù)據(jù)的長(zhǎng)度*/

functionge:Length(x:number|string){

if((<string>x).length{

return(xasstring)length

}else{

returnx.toString(]length

)

}

console.locKaetLenothCabcd'),aetLength(1234))

類型推斷

類型推斷:TS會(huì)在沒有明確的指定類型的時(shí)候推測(cè)出一個(gè)類型

有下面2種情況:1.定義變量時(shí)賦值了,推斷為對(duì)應(yīng)的類型.2.定義變量時(shí)沒有賦值推斷為any類型

「定義變量時(shí)賦值了,推斷為對(duì)應(yīng)的類型7

letb9=123/number

/b9='abc'/error

「定義變段殳胸值,推斷為any類型7

letb10Iany類型

b10=123

b10='abc'

2.2接口

Typescript的核心原則之一是對(duì)值所具有的結(jié)構(gòu)進(jìn)行類型檢直.我們使用接口(Interfaces)來定義對(duì)象的類型.接口是對(duì)象的狀態(tài)據(jù)性)和

行為(方法)的抽象(描述)

接口初探

需求:創(chuàng)建人的對(duì)象,需要對(duì)人的屬性進(jìn)行一定的約束

id是number類型,必須有,只讀的

name是string類型,必須有

age是number類型,必須有

sex是strin聯(lián)型,可5殳有

下面通過一個(gè)簡(jiǎn)單示例來觀察接口是如何工作的:

在Typescript中,我們使用閱y(Interfaces)來定義對(duì)象的類型

接口:是對(duì)象的狀態(tài)隔性)和行為6法)的抽象(描述)

接口類型的對(duì)象

多了或者少了屬性是不允許的

可選屬性:?

只讀屬性:readonly

*/

r

需求:創(chuàng)建乂的對(duì)象,需要對(duì)人的屬性迸行一定的約束

id昌lumber類型,有,只讀的

name懸tring類里,必須有

age是number類型,必須有

sex是string類型,可以沒有

7

/定義人的汶口

interfaceIPerson[

idnumber

namestring

age:number

sexstring

}

constpersonl:IPerson={

id:1,

name'tom',

age20,

sex:'男?

)

類型檢查器會(huì)查看對(duì)象內(nèi)部的屬性是否與Person接口描述一致,如果不一致就會(huì)提示類型錯(cuò)誤。

可選屬性

接口里的屬性不全都是必需的。有些是只在某些條件下存在,或者根本不存在。

interfaceIPerson[

idnumber

namestring

age:number

sex?:string

)

帶有可選屬性的接口與普通的接口定義差不多,只是在可選屬性名字定義的后面加一個(gè)?符號(hào).

可選屬性的好處之一是可以對(duì)可能存在的屬性進(jìn)行預(yù)定義,好處之二是可以捕獲引用了不存在的屬性時(shí)的錯(cuò)誤.

constperson2IPerson={

id1,

name'tom',

age:20,

isex:'男,/可以沒有

)

只讀屬性

一些對(duì)象屬性只能在對(duì)象剛剛創(chuàng)建的時(shí)候修改其值.你可以在屬性名前用readonly來指定只讀屬性:

interfaceIPerson[

readonlyid:number

name:string

age:number

sex?:string

}

一旦賦值后再也不能被改變了。

constperson2IPerson={

id:2,

name'tom',

age:20,

isex「男”可以沒有

/XXX:12/error沒有在接口中定義,不能有

}

person2id=2/error

readonlyvsconst

最簡(jiǎn)單判斷該用readonly還是const的方法是看要把它做為變量使用還是做為一個(gè)屬性.做為變量使用的話用const,若做為屬性則使

用readonly。

函數(shù)類型

接口能夠描述JavaScript中對(duì)象擁有的各種各樣的外形.除了描述帶有屬性的普通對(duì)象外,接口也可以描述函數(shù)類型。

為了使用接口表示函數(shù)類型,我們需要給接口定義一個(gè)調(diào)用簽名.它就像是一個(gè)只有參數(shù)列表和返回值類型的函數(shù)定義。參數(shù)列表里的每

個(gè)參數(shù)都需要名字和類型.

/*

如可以懿函數(shù)類型(參數(shù)的類型與返回的類型)

7

interfaceSearchFunc{

sourcestring,subStringstring):boolean

}

這樣定義后,我們可以像使用其它接口一樣使用這個(gè)函數(shù)類型的接口.下例展示了如何創(chuàng)建一個(gè)函數(shù)類型的變量,并將一個(gè)同類型的函

數(shù)賦值給這個(gè)變量。

constmySearchSearchFunc=functionsourcestringsubstring):boolean{

returnsourcesearch*sub)>-1

)

console.log(mySearch('abccl','be'))

類類型

類實(shí)現(xiàn)接口

與C#或Java里接口的基本作用一樣,Typescript也能夠用它來明確的強(qiáng)制一個(gè)類去符合某種契約。

/*

類類型:實(shí)現(xiàn)距

1.一個(gè)類可以實(shí)現(xiàn)多個(gè)妒

2.一個(gè)奴可以繼承多個(gè)接

□7

interfaceAlarm

alertQ:any;

}

interfaceLight{

lightOn():void;

lightOff():void:

}

classCarimplementsAlarm

alert(){

console.log('Caralert');

}

)

一個(gè)類可以實(shí)現(xiàn)多個(gè)接口

classCar2inplementsAlarmLight!

alertO{

console.log('Caralert');

}

lightOn()(

console.logCCarlighton');

}

lightOff(){

console.logCCarlightoff');

}

}

接口繼承接口

和類一樣,接口也可以相互繼承。這讓我們能夠從一個(gè)接口里復(fù)制成員到另一個(gè)接口里,可以更靈活地將接口分割到可重用的模塊里。

interfaceLightableAlarmextendsAlarmLight{

)

2.3類

對(duì)于傳統(tǒng)的JavaScript程序我們會(huì)使用函數(shù)和基于原型的繼承來創(chuàng)建可重用的組件,但對(duì)于熟悉使用面向?qū)ο蠓绞降某绦騿T使用這些語法

就有些棘手,因?yàn)樗麄冇玫氖腔陬惖木S承并且對(duì)象是由類構(gòu)建出來的。從ECMAScript2015,也就是ES6開始,JavaScript程序員

將能夠使用基于類的面向?qū)ο蟮姆绞健J褂肨ypescript,我們?cè)试S開發(fā)者現(xiàn)在就使用這些特性,并且編譯后的JavsScript可以在所有主

流瀏覽器和平臺(tái)上運(yùn)行,而不需要等到下個(gè)JavaScript版本。

基本示例

下面看一個(gè)使用類的例子:

/,

類的基本定義與使用

*/

classGreeter{

,聲明屬性

messagestring

i構(gòu)造方法

constructor(messagestring){

thismessage=message

}

/一般方法

greet():string{

return'Hello'+thismessage

)

}

/創(chuàng)建類的實(shí)例

constgreeter=newGreeterworld')

i調(diào)用實(shí)例的方法

console.logfgreeter.greet())

如果你使用過C#或Java,你會(huì)對(duì)這種語法非常熟悉。我們聲明一個(gè)Greeter類。這個(gè)類有3個(gè)成員:一個(gè)叫做message的屬性,一

個(gè)構(gòu)造函數(shù)和—個(gè)greet方法.

你會(huì)注意到,我們?cè)谝萌魏我粋€(gè)類成員的時(shí)候都用了this.它表示我們?cè)L問的是類的成員.

后面一行,我們使用new構(gòu)造了Greeter類的一個(gè)實(shí)例。它會(huì)調(diào)用之前定義的構(gòu)造函數(shù),創(chuàng)建一個(gè)Greeter類型的新對(duì)象,并執(zhí)行構(gòu)造

函數(shù)初始化它。

最后一行通過greeter對(duì)象調(diào)用其greet方法

繼承

在Typescript里,我們可以使用常用的面向?qū)ο竽J健;陬惖某绦蛟O(shè)計(jì)中一種最基本的模式是允許使用繼承來獷展現(xiàn)有的類.

看下面的例子:

/,

類的繼承

*/

classAnimal;

run(distancenumber){

console.logfAnimalrun${distancefm)

}

)

classDogextendsAnimal{

cry(){

console.log('wang!wang!')

)

}

constdog=newDog()

dog.cryO

dog/可以調(diào)再從父中繼承得到的^法

這個(gè)例子展示了最基本的繼承:類從基類中繼承了屬性和方法。這里,Dog是一個(gè)派生類,它派生自Animal基類,通過extends關(guān)

鍵字.派生類通常被稱作子類,基類通常被稱作超當(dāng)

因?yàn)镈og繼承了Animal的功能,因此我們可以創(chuàng)建一個(gè)Dog的實(shí)例,它能夠cry()和run()0

下面我們來看個(gè)更加復(fù)雜的例子。

classAnimal{

namestring

cunblruulur(ruiiiie.siring){

=name

}

run{distancenumber=O){

console.log(${thisnamerunS{distancefm)

}

)

classSnakeextendsAnimal

constructor(namestring){

/碉父類型校管方法

supername

)

/重寫父類型峭去

run(distancenumber=5){

console.log('sliding...,)

super.run(distance

}

)

classHorseextendsAnimal{

constructor(namestring){

崛父類型構(gòu)窗法

supername

}

/重寫文類型的方法

run(distancenumber=50){

console.k)g('dashing...')

/調(diào)用眾類型的一般方法

super.run(distance

)

XXX(){

console.log('xxx(),)

}

)

constsnake=newSnake('sn')

snakerun()

consthorse=newHorse['ho')

horserun()

位類型弓隔指向子類型的實(shí)例=?多水

consttomAnimal=newHorseho22')

tom.run()

尸如黯■類矍沒有擴(kuò)展的方法,可以讓子類型弓用指際類型的實(shí)例^

consttom3Snake=newAnimaltom3')

tom3.run()

r如果子類里有擴(kuò)展的萬法,不能il子類型弓周指向爻類型的實(shí)砌

/consttorr2:Horse=newAnimal('tom2')

/tom2.run()

這個(gè)例子展示了一些上面沒有提到的特性。這一次,我們使用extends關(guān)鍵字創(chuàng)建了Animal的兩個(gè)子類:Horse和Snake。

與前一個(gè)例子的不同點(diǎn)是,派生類包含了一個(gè)構(gòu)造函數(shù),它必須調(diào)用super。,它會(huì)執(zhí)行基類的構(gòu)造函數(shù)。而且,在構(gòu)造函數(shù)里訪問

this的屬性之前,我們一定要調(diào)用superO0這個(gè)是TypeScript強(qiáng)制執(zhí)行的一條重要規(guī)則。

這個(gè)例子演示了如何在子類里可以重寫父類的方法。Snake類和Horse類都創(chuàng)建了run方法,它們重寫了從Animal繼承來的run方法,

使得run方法根據(jù)不同的類而具有不同的功能。注意,即使tom被聲明為Animal類型,但因?yàn)樗闹凳荋orse,調(diào)用tom.run(34)時(shí),

它會(huì)調(diào)用Horse里重寫的方法。

sliding...

snrun5m

dashing...

horun50m

公共,私有與受保護(hù)的修飾符

默認(rèn)為public

在上面的例子里,我們可以自由的訪問程序里定義的成員。如果你對(duì)其它語言中的類比較了解,就會(huì)注意到我們?cè)谥暗拇a里并沒有

使用public來做修飾;例如,C#要求必須明確地使用public指定成員是可見的.在Typescript里,成員都默認(rèn)為public.

你也可以明確的將一個(gè)成員標(biāo)記成public,我們可以用下面的方式來重寫上面的Animal類:

理解private

當(dāng)成員被標(biāo)記成private時(shí),它就不能在聲明之的類的外部訪問。

理解protected

protected修飾符與private修飾符的行為很相似,但有一點(diǎn)不同,protected成員在派生類中仍然可以訪問.例如:

/,

訪問修飾符用來描述類內(nèi)部的屬性亦法的可訪問性

public:默認(rèn)值公開的外部也可以訪問

private:兵能類內(nèi)部可以訪問

protected:類內(nèi)部f吁類可以訪問

*/

classAnimal{

publicnamestring

publicconstructornamestring){

=name

}

publicrun(distancenumber=0){

console.loa(S{thisnamerunS{distance}m)

}

}

classPersonextendsAnimal{

privateage:number=18

protectedsexstring='男'

run(distancenumber=5){

console.log('Personjumping...,)

super.run(distance

}

)

classStudentextendsPerson{

run(distancenumber=6){

console.log('Studentjumping...,)

console.log(thissex)仔類能看到皮類中受保護(hù)的成員

/console.log(this.age)/子類看不到‘爻類中私有的成員

super.run(distance

}

}

console.Iog(newPerson('abc').name)/公開的可見

/console.logfnewPerson('abc').sex)I受保護(hù)的不可見

/console.Iog(newPerson('abc').age)/私有的不可見

readonly修飾符

你可以使用readonly關(guān)鍵字將屬性設(shè)置為只讀的.只讀屬性必須在聲明時(shí)或構(gòu)造函數(shù)里被初始化。

classPerson;

readonlynamestring='abc'

constructorsnamestring){

=name

}

)

letjohn=newPerson'John')

/='peter'/error

參數(shù)屬性

在上面的例子中,我們必須在Person類里定義一個(gè)只讀成員name和一個(gè)參數(shù)為name的構(gòu)造函數(shù),并且立刻將name的值賦給

,這種情況經(jīng)常會(huì)遇到。參數(shù)屬性可以方便地讓我們?cè)谝粋€(gè)地方定義并初始化一個(gè)成員。下面的例子是對(duì)之前Person類的修

改版,使用了參數(shù)屬性:

classPerson2

constructorreadonlynamestring){

}

constp=newPerson2jack')

console.log:pname

注意看我們是如何舍棄參數(shù)name,僅在構(gòu)造函數(shù)里使用readonlyname:string參數(shù)來創(chuàng)建和初始化name成員。我|門把聲明和賦值合并

至一處。

參數(shù)屬性通過給構(gòu)造函數(shù)參數(shù)前面添加一個(gè)訪問限定符來聲明。使用private限定一個(gè)參數(shù)屬性會(huì)聲明并初始化一個(gè)私有成員;對(duì)于

public和protected來說也是一樣。

存取器

Typescript支持通過getters/setters來截取對(duì)對(duì)象成員的訪問.它能幫助你有效的控制對(duì)對(duì)象成員的訪問.

下面來看如何把一個(gè)簡(jiǎn)單的類改寫成使用get和set8首先,我們從一個(gè)沒有使用存取器的例子開始。

classPerson;

firstName:string="A'

lastName:string='B'

getfullName(){

returnthisfirstName++this.lastName

)

setfullName(value){

constnames二valuesplit('-')

thisfirstNamenames!0]

this.lastName=names[1]

}

}

constp=newPerson)

console.logfpfullName

pfirstName='C'

plastName='D'

console.logfpfullName

pfullName='E-F'

console.log;pfirstNameplastName)

靜態(tài)屬性

到目前為止,我們只討論了類的實(shí)例成員,那些僅當(dāng)類被實(shí)例化的時(shí)候才會(huì)被初始化的屬性。我們也可以創(chuàng)建類的靜態(tài)成員,這些屬性存

在于類本身上面而不是類的實(shí)例上。在這個(gè)例子里,我們使用static定義origin,因?yàn)樗撬芯W(wǎng)格都會(huì)用到的屬性。每個(gè)實(shí)例想要訪

問這個(gè)屬性的時(shí)候,都要在origin前面加上類名。如同在實(shí)例屬性上使用this.xxx來訪問屬性一樣,這里我們使用Grid.xxx來訪問靜態(tài)

屬性。

/*

靜態(tài)屬性,是類對(duì)象的屬性

關(guān)靜態(tài)屬性.是類的實(shí)例對(duì)象的屬性

7

classPerson;

namel:sting='A'

staticnan^2string='B"

}

console.logPersonname2)

console.log(newPersonnamel)

抽象類做為其它派生類的基類使用.它們不能被實(shí)例化。不同于接口,抽象類可以包含成員的實(shí)現(xiàn)細(xì)節(jié),abstract關(guān)鍵字是用于定義抽象

類和在抽象類內(nèi)部定義抽象方法。

‘抽象類

不能創(chuàng)建實(shí)只有實(shí)現(xiàn)類才能創(chuàng)建實(shí)例

可以包含未實(shí)現(xiàn)的抽象方法

*/

abstractclassAnimal:

abstractcry()

run(){

console.tog('runO,)

)

}

classDogextendsAnimal{

cry(){

console.logCDogcry(),)

)

}

constdog=newDogi

dogcry()

dogrun()

2.4函數(shù)

函數(shù)是JavaScript應(yīng)用程序的基5出,它幫助你實(shí)現(xiàn)抽象層,模擬類,信息隱藏和噗塊。在TypeScript里,雖然已經(jīng)支持類,命名空間

和模塊,但函數(shù)仍然是主要的定義行為的地方.Typescript為JavaScript函數(shù)添加了額外的功能,讓我們可以更容易地使用.

基本示例

和JavaScript一樣,TypeScript函數(shù)可以創(chuàng)建有名字的函數(shù)和匿名函數(shù)。你可以隨意選擇適合應(yīng)用程序的方式,不論是定義一系列API

函數(shù)還是只使用一次的函數(shù)。

通過下面的例子可以迅速回想起這兩種JavaSzript中的函數(shù):

,命名函數(shù)

functionadd(x.y){

returnx+y

)

/匿名函數(shù)

letmyAdd=function(xy){

returnx+y:

)

函數(shù)類型

為函數(shù)定義類型

讓我們?yōu)樯厦婺莻€(gè)函數(shù)添加類型:

functionadd(x:numbery:number):number{

returnx+y

}

letmyAdd=function(x:number,y:number):number{

returnx+y

)

我們可以給每個(gè)參數(shù)添加類型之后再為函數(shù)本身添加返回值類型.TypeScript能夠根據(jù)返回語句自動(dòng)推斷出返回值類型.

書寫完整函數(shù)類型

現(xiàn)在我們已經(jīng)為函數(shù)指定了類型,下面讓我們寫出函數(shù)的完整類型。

letmyAdd2(xnumbery:number)=>number=

function(xnumber.ynumber):number{

returnx+y

)

可選參數(shù)和默認(rèn)參數(shù)

Typescript里的每個(gè)函數(shù)參數(shù)都是必須的。這不是指不能傳遞null或undefined作為參數(shù),而是說編譯器檢查用戶是否為每個(gè)參數(shù)都傳

入了值。編譯器還會(huì)假設(shè)只有這些參數(shù)會(huì)被傳遞進(jìn)函數(shù).簡(jiǎn)短地說,傳遞給一個(gè)函數(shù)的參數(shù)個(gè)數(shù)必須與函數(shù)期望的參數(shù)個(gè)數(shù)一致.

JavaScript里,每個(gè)參數(shù)都是可選的,可傳可不傳。沒傳參的時(shí)候,它的值就是undefined。在TypeScript里我們可以在參數(shù)名旁使

用?實(shí)現(xiàn)可選參數(shù)的功能。比如,我們想讓lastName是可選的:

在TypeScript里,我們也可以為參數(shù)提供一個(gè)默認(rèn)值當(dāng)用戶沒有傳遞這個(gè)參數(shù)或傳遞的值是undefined時(shí)。它們叫做有默認(rèn)初始化值

的皴。讓我們修改上例,把firstName的默認(rèn)值設(shè)置為“A”。

functionbuildNameifirstName:strings'A',lastName?:string):string{

if(lastName?{

returnfirstName++lastName

}else{

returnfirstName

}

}

console.logthuildNameCC,'D'))

console.lo^buildNameCC'))

console.log(buildName())

剩余參數(shù)

必要參數(shù),默認(rèn)參數(shù)和可選參數(shù)有個(gè)共同點(diǎn):W們表示某一個(gè)參數(shù).有時(shí),你想同時(shí)操作多個(gè)參數(shù),或者你并不知道會(huì)有多少參數(shù)傳遞進(jìn)

來。在JavaScript里,你可以使用arguments來訪問所有傳入的參數(shù)。

在TypeScript里,你可以把所有參數(shù)收集到一個(gè)變量里:

剩余參數(shù)會(huì)被當(dāng)做個(gè)數(shù)不限的可選參數(shù)??梢砸粋€(gè)都沒有,同樣也可以有任意個(gè)。編譯器創(chuàng)建參數(shù)數(shù)組,名字是你在省略號(hào)(…)后面

給定的名字,你可以在函數(shù)體內(nèi)使用這個(gè)數(shù)組,

functioninfo(x:string,argsstringO){

console.log(xargs)

)

infofabcW.V/a')

函數(shù)重載

函數(shù)重載:函數(shù)名相同,而形參不同的多個(gè)函數(shù)

在JS中,由于弱類型的特點(diǎn)和形參與實(shí)參可以不匹配,是沒有函數(shù)重載這一說的

但在TS中,與其它面向?qū)ο蟮恼Z言(如Java)就存在此語法

/,

函數(shù)名相同,而形參不同的多個(gè)函數(shù)

就我們有一個(gè)add函數(shù),它可以接收"、tring類型的第面拼接,也可以接收坊number類型的例面相加

7

/重載函數(shù)聲明

functionadd(x:string,y:string):string

functionadd(xnumbery:number):number

1定義函數(shù)實(shí)現(xiàn)

functionadd(x:string|number,y:string|number):string|number{

/酶現(xiàn)上我們要注意嚴(yán)格判斷兩個(gè)參數(shù)的類型是否相等,而不能簡(jiǎn)單的寫一個(gè)x+y

if(typeofx==="string'&&typeofy==="string'){

returnx-y

}elseif(typeofx==='number'&&typeofy==='number'){

returnx-y

}

}

console.log(add(1.2))

console.log[add('a',"b'))

/console.log(add(1,'a"))/error

2.5泛型

指在定義函數(shù)、接口或類的時(shí)候,不預(yù)先指定具體的類型,而在使用的時(shí)候再指定具體類型的一種特性。

引入

下面創(chuàng)建一個(gè)函數(shù),實(shí)現(xiàn)功能:根據(jù)指定的數(shù)量count和數(shù)據(jù)value,創(chuàng)建一個(gè)包含count個(gè)value的數(shù)組

不用泛型的話,這個(gè)函數(shù)可能是下面這樣:

functioncreateArray(value:any,countnumber):aryQ{

constarr:any[]=[]

for(letindex=0;index<countindex++){

arrpushvalue

}

returnarr

)

constarr1=createArray(11,3)

constarr2=createArray('aa",3)

console.logarrl0].toFixed()arr2[0].split("))

使用函數(shù)泛型

functioncreateArray2<T>ivalueTcountnumber){

constarr:Array<T>=0

for(letindex=0;index<countindex++){

arr.pushvalue

}

returnarr

}

constarr3-createArray2<number>(11.3)

console.log(arr3[;0].toFixed())

/console.log(arr3[0].split("))/error

constarr4createArray2<string>('aa',3)

console.log(arr4[0].split("))

/console.log(arr4[0].toFlxed())/error

多個(gè)泛型參數(shù)的函數(shù)

functionswap:K,V>(a:K.bV):[K.V]{

returnab]

)

c51slresullswup<slri“g,nuinbtsr^'ubv',123)

console.log(result[0].length.result[1].toFlxed())

泛型接口

在定義接口時(shí),為接口中的屬性或方法定義泛型類型

在使用接口時(shí),再指定具體的泛型類型

interfaceIbaseCRUD<T>{

dataTO

add:(t:T)=>void

getByld(idnumber)T

)

classUser|

id?:number;//d壬奢

namestring;/姓名

age:number;1年齡

constructorinameagei{

this.name=name

this.age=age

}

}

classUserCRUDimpleme

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論