TypeScript
什么是TypeScript
TypeScript就是所謂JavaScript的超集,TypeScript允許程序員在其代碼中使用面向?qū)ο蟮臉?gòu)造拒名,然后將其轉(zhuǎn)化為JavaScript
TypeScript的好處
- 靜態(tài)類型,typescript代碼比JavaScript代碼更易于預(yù)測和更易于調(diào)試
- 面向?qū)ο蟮墓δ埽K和命名空間)使組織大型代碼庫更易于管理
- 編譯步驟在達(dá)到運(yùn)行時(shí)之前捕獲錯(cuò)誤
- 流行框架angular是用typescript編寫的
- typescript類似于coffeescript,另一種編譯為javascript的語言,不過由于靜態(tài)類型圃郊,前者比后者更加靈活
1. 安裝和設(shè)置
npm install typescript -g
tsc helloword.ts
2. 編譯為javascript(vscode)
-
tsc --init
生成一個(gè)tsconfig.json
文件 - 修改文件
"outDir": "./js"
- 點(diǎn)擊
任務(wù)
- 運(yùn)行任務(wù),選擇
監(jiān)視tsconfig
3. TS中的數(shù)據(jù)類型(11)
- 布爾(boolean)
- 字符串(string)
- 數(shù)值(number)
- undefined
var num:number|undeined
- null
- 數(shù)組(Array): 兩種定義方法
var arr:number[] = [1, 2, 3] var arr:Array<number> = [1, 2, 3]
- 任意(any)
- 枚舉(enum): 用一定的單詞代表某些信息
enum Flag { success= 1, error= 2 } var flag:Flag = Flag.success console.log(flag) //1
enum Flag { success, error } var flag:Flag = Flag.success console.log(flag) //0 當(dāng)沒有給類型中的變量名賦值時(shí)女蜈,它的值為下標(biāo)持舆,如果改變了其中的數(shù)值,之后的數(shù)值會(huì)累加下去
- void: 定義方法時(shí)該方法沒有返回值
function getInfo():void{ ... }
- 元組類型(tuple):屬于數(shù)組的一種
var arr:[number, string] = [1, 'a'] //正確 var arr:[number, string] = ['a', 2] //錯(cuò)誤
- never: 1.從不會(huì)出現(xiàn)的值 2. undefined和null屬于never中的一種
4. TypeScript中的函數(shù)
- 定義
function getInfo():number{ return 123 } var getInfo = function():number{ return 123 }
- 方法可選參數(shù)(表示參數(shù)可傳可不傳)
可選參數(shù)一定要配置到參數(shù)的最后面
function getInfo(num:number, num1?:number):number{ if(num1){ return num + num1 }else{ return num } } alert(getInfo(1))
- 默認(rèn)參數(shù)
function getInfo(num:number=11):number{ return num }
- 剩余參數(shù)
function getInfo(...rest:number[]):number{ var num:number = 0 for(var i:number = 0 ; i < rest.length ; i++){ num += rest[i] } return num } getInfo(1, 2, 3, 4) //10 getInfo() //0
- 函數(shù)重載(通過傳入不同的參數(shù)實(shí)現(xiàn)不同的功能)
function getInfo(name:string):string function getInfo(name:string, age:number):string function getInfo(name:any, age?:any):string{ if(age){ return `我的名字是${name},我的年齡是${age}` } return `我的名字是${name}` }
- 箭頭函數(shù)
3. 靜態(tài)打字
4. 數(shù)組
5. 接口
- 屬性類接口
interface FullName{ firstName:string; secondName?:string; //可選屬性 } function getInfo(info:FullName):void{ console.log(info.firstName + '--' + info.secondName) } getInfo({ firstName: 'ou', secondName: 'chi' })
- 函數(shù)類型接口
interface entry { (key:string, value:string):string } var md5:entry = function(key:string,value:string):string{ return `key:${key}--value:${value}` }
- 可索引接口(對象伪窖,數(shù)組的約束)(不常用)
interface UserArr { [index:number]: string }
- 類類型接口(和抽象類有點(diǎn)相似)
class Dog implements(實(shí)現(xiàn)) Animal
interface Animal { name: string; eat():void; } class Dog implements Animal { public name:string; constructor(name:string){ this.name = name } eat():void{ console.log(this.name) } } var d1 = new Dog('dogdog') d1.eat()
- 接口拓展(接口可繼承)
interface Animal { name: string } interface Person { age: number } class Web implements Person { name: string age: number constructor(name:string, age:number){ this.name = name this.age = age } getInfo():void{ console.log(this.name + '--' + this.age) } }
6. 類
- 定義類
class Person { name:string; constructor(name:string){ this.name = name } run():void{ console.log(this.name + '在運(yùn)動(dòng)') } } var p = new Person('張三') p.run()
- ts中實(shí)現(xiàn)繼承
class Person { name:string; constructor(name:string){ this.name = name } work():void{ console.log(this.name + '在工作') } } class Web extends Person { constructor(name:string){ super(name) } } var w1 = new Web('程序員') w1.work()
- 繼承的探討逸寓,子類方法與父類一致
子類方法會(huì)覆蓋父類的方法
- 類中的修飾符
- public(公有的)
在類內(nèi)部、子類覆山、類外部都可以訪問到該屬性或方法
class Person { public name:string; constructor(name:string){ this.name = name } } var p1 = new Person('王五') console.log(p1.name)
- protected(受保護(hù)的)
在內(nèi)部竹伸、子類中可以訪問到該屬性或方法,在類外部不能訪問到該屬性或方法
class Person { protected name:string; constructor(name:string){ this.name = name } } class Web extends Person { constructor(name:string){ super(name) } eat():void{ console.log(this.name + 'eating') //子類中可以訪問到該屬性 } } var p1 = new Person('王五') var web1 = new Web('小六') web1.eat() // console.log(p1.name) //會(huì)報(bào)錯(cuò)簇宽,因?yàn)轭愅獠坎荒茉L問protected屬性 // console.log(web1.name) //會(huì)報(bào)錯(cuò)勋篓,因?yàn)轭愅獠坎荒茉L問protected屬性
- private(私有的)
只能在類內(nèi)部訪問到該屬性或方法
class Person { protected name:string; constructor(name:string){ this.name = name } } class Web extends Person { constructor(name:string){ super(name) } eat():void{ console.log(this.name + 'eating') //報(bào)錯(cuò) } } var p1 = new Person('王五') var web1 = new Web('小六') web1.eat() // console.log(p1.name) //會(huì)報(bào)錯(cuò)吧享,因?yàn)轭愅獠坎荒茉L問private屬性 // console.log(web1.name) //會(huì)報(bào)錯(cuò),因?yàn)轭愅獠坎荒茉L問private屬性
- public(公有的)
- 靜態(tài)屬性譬嚣、靜態(tài)方法(static)
- 加個(gè)static關(guān)鍵詞就是靜態(tài)方法或者靜態(tài)屬性
- 靜態(tài)方法不能直接調(diào)用實(shí)例屬性和方法
- 靜態(tài)方法只能調(diào)用靜態(tài)屬性和方法钢颂??
- 多態(tài)
在父類中定義方法但是不去實(shí)現(xiàn)拜银,讓它的子類去實(shí)現(xiàn)殊鞭,每個(gè)子類有不同的表現(xiàn) - 抽象類(abstract)
抽象類不能直接被實(shí)例化,它其實(shí)類似一個(gè)標(biāo)準(zhǔn),提供一個(gè)基類盐股,規(guī)定抽象類中的子類必須實(shí)現(xiàn)基類中的抽象方法 abstract class Person { abstract run():void } class Web extends Person { run(){ console.log('run') } } var w1 = new Web() w1.run()
7. 泛型
解決類钱豁,接口,方法的可復(fù)用性,以及對不特定的數(shù)據(jù)類型的支持
- 函數(shù)泛型
function getInfo<T>(value:T):T{ console.log(value) } getInfo<number>(15) getInfo<string>('abc')
- 類泛型
class MinClass<T>{ public list:T[] = [] add(value:T):void{ this.list.push(value) } sort():any{ var min:T = this.list[0] for(var i:number = 0 ; i < this.list.length ; i++){ if(this.list[i] < min){ min = this.list[i] } } return min } } var m1 = new MinClass<number>() m1.add(1) m1.add(2) m1.add(-1) m1.add(-5) m1.add(10) alert(m1.sort())
- 接口泛型
interface Config { <T>(key:T,value:T):T } var getInfo:Config = function<T>(key:T,value:T):T{ console.log(`${key}--${value}`) } getInfo<number>(1,2)
- 把類當(dāng)做參數(shù)的泛型類
例子:定義一個(gè)操作數(shù)據(jù)庫的庫 要求:有add疯汁、get、update卵酪、delete方法 interface Dbi<T> { add(info:T):boolean get(id:number):boolean delete(id:number):boolean update(info:T,id:number):boolean } class User<T> implements Dbi<T>{ add(info: T): boolean { console.log(info) return true } get(id: number): boolean { throw new Error("Method not implemented.") } delete(id: number): boolean { throw new Error("Method not implemented.") } update(info: T, id: number): boolean { throw new Error("Method not implemented.") } } class U { username:string|undefined password:string|undefined } var u = new U() u.username = '123' u.password = '789' var user = new User<U>() user.add(u)
8. 模塊和命名空間
import和export(瀏覽器中不能直接執(zhí)行幌蚊,要通過nodejs)
9. 裝飾器
- 類裝飾器
傳入一個(gè)參數(shù) 對靜態(tài)成員來說是構(gòu)造函數(shù),對實(shí)例成員來說是類的原型對象 function logClass(params:any){ return function(target:any){ console.log(target) console.log(params) } } @logClass('aaa') class Per { }
- 屬性裝飾器
傳入兩個(gè)參數(shù) 1. 對靜態(tài)成員來說是類的構(gòu)造函數(shù)溃卡,對實(shí)例成員來說是類的原型對象 2. 屬性的名稱 function logAttr(params:any){ return function(target:any, attrName:string){ console.log(target.constructor) console.log(attrName) } } @logClass('aaa') class Per { @logAttr('as') public username:string|undefined }
- 方法裝飾器
傳入三個(gè)參數(shù) 1. 對靜態(tài)成員來說是類的構(gòu)造函數(shù)溢豆,對實(shí)例成員來說是類的原型對象 2. 方法的名稱 3. 方法的屬性描述符 function logFn(params:any){ return function(target:any, name:string, des:any){ console.log(target) console.log(name) console.log(des) } } @logClass('aaa') class Per { @logAttr('as') public username:string|undefined @logFn('bbc') add():void{} }
- 方法參數(shù)裝飾器
傳入三個(gè)參數(shù) 1. 對靜態(tài)成員來說是類的構(gòu)造函數(shù),對實(shí)例成員來說是類的原型對象 2. 方法的名稱 3. 參數(shù)在函數(shù)列表中的索引