TypeScript是開源的項目,由微軟開發和維護,所以最初只有微軟的 Visual Studio 支持。如今,出現了更多自己支持或者經過插件支持 TypeScript 語法、智能提示、糾錯、甚至是內置編譯器的文本編輯器和IDE。html
主類型:node
string、number、boolean
特殊類型:typescript
null、undefined、symbol(ES6)
基礎類型聲明與使用:npm
string: let name: string = ‘Alice’; let desc: string = `my name is ${name}`; number: let norm: number = 666; let binaryNum: number = 0b111; let hexNum: number = 0xfff; let octalNum: number = 0o17; let nan: number = NaN; let infinity: number = Infinity; boolean: let yet: boolean = true; let flag: boolean = Boolean(0); null: let n: null = null; undefined: let u: undefined = undefined; symbol: let s: Symbol = Symbol(2); void: let v2: void = null; let v5: void = undefined;
let name: string = ‘Tom’; name = 666; demo.ts(2,1): error TS2322: Type '666' is not assignable to type 'string'.
使用any類型: ``` let name: any = ‘Tom’; name = 666; ``` 隱式任意值類型: let name; name = ‘Tom’; name = 666; 等價於: let name : any; name = ‘Tom’; name = 666;
TS會在沒有明確指定類型的時候推測出一個類型,這就是類型推論編輯器
let user = ‘Tom’; user = 666; demo.ts(2,1): error TS2322: Type '666' is not assignable to type 'string'.
TS中的聯合類型表示取值可爲多種類型中的一種:函數
let user: string | number; user = 666; user = ‘Tom’;
訪問聯合類型的屬性或方法時,只能訪問全部類型的共有方法:工具
function test(param: string|number){ return param.length; } demo.ts(2,18): error TS2339: Property 'length' does not exist on type 'string | number’.
類型斷言能夠手動指定一個值的類型,可是類型斷言不是強制類型轉換,TypeScript編譯器不支持強制類型轉換。開發工具
function test(param: number|string){ if((<string>param).length) return (<string>param).length; else return param.toString().length }
interface Sport { name: string, teamwork: boolean } let football: Sport = { name: 'soccer', teamwork: true }
可選屬性:this
interface Sport { name: string, teamwork: boolean, needPg?: boolean } let football: Sport = { name: 'soccer', teamwork: true }
任意屬性:.net
interface Sport { name: string, teamwork: boolean, needPg?: boolean, [other: string]: any } let football: Sport = { name: 'soccer', teamwork: true, needPg: true, count: 22 }
一旦定義任意屬性,那麼肯定屬性和可選屬性的類型必須是它的子屬性
只讀屬性:
interface Sport { readonly name: string, teamwork: boolean } let football: Sport = { name: 'soccer', teamwork: true }
函數聲明
function avg(x: number,y:number):number{ return (x+y)/2; }
函數表達式
let avg = function(x:number,y:number):number{ return (x+y)/2; }
or
let avg: (x:number,y:number) => number = function(x:number,y:number):number{ return (x+y)/2; }
函數可選參數:
function avg(x: number,y?:number):number{ if(y){ return (x+y)/2; }else{ return x; } }
可選參數必須在必選參數的後面
函數的可選參數與默認值:
function avg(y:number = 10,x: number):number{ if(y){ return (x+y)/2; }else{ return x; } }
TypeScript會將添加默認值的參數識別爲可選參數,此時不受「可選參數必須在必選參數的後面」的限制
函數重載:
TypeScript中經過爲一個函數進行屢次函數定義,並實現函數完成重載
function reverse(x: number): number; function reverse(x: string): string; function reverse(x: any):any{ if(typeof x == ‘number’){ return Number(x.toString().split(‘’).reverse().join(‘’)); }else{ return x.split(‘’).reverse().join(‘’); } }
面向對象的函數重載:
interface A{ say(x:number); say(x:string); } class AA implements A{ say (x:any){ if(typeof x == ‘string’) console.log(‘string’,x); else console.log(‘number’,x); } } console.log((new AA()).say(1)); console.log((new AA()).say('123'));
該類型約束值只能是某幾個字符串的一個,這是在編譯器層面作的約束,並不會改變生成的js代碼
type Name = 'abc' | 'def' | 'mn'; function demo(e: Name): void{ console.log(e); } demo(‘abc');
class Block { private hash: string; private prevHash: string; private nonce: number; constructor (hash: string, prevHash: string, nonce = 0){ this.hash = hash; this.prevHash = prevHash; this.nonce = nonce; } public get $hash(): string { return this.hash; } public set $hash(value: string) { this.hash = value; } public get $prevHash(): string { return this.prevHash; } public set $prevHash(value: string) { this.prevHash = value; } public get $nonce(): number { return this.nonce; } public set $nonce(value: number) { this.nonce = value; } public computeHash(){ let sha256 = crypto.createHash('sha256'); sha256.update(`${this.prevHash}${this.nonce.toString(16)}`,'utf8'); let hash = sha256.digest('hex'); return hash; } }
TypeScript中抽象類不容許被實例化
abstract class BtcBlock { public abstract computeHash(x:string):string; } class Block extends BtcBlock { public computeHash(x:string):string{ return `btc${x}`; }; }
上節已提到,TS中的接口就是抽象多個類的共有屬性與方法,做爲對象的類型而存在
interface Alarm { alert(): void; } interface Light { lightOn(): void; lightOff(): void; } class Auto implements Alarm, Light { alert(){ console.log('car alart'); } lightOn(){ console.log('car light on'); } lightOff(){ console.log('car light off'); } }
即在定義類、函數或接口時不指定具體類型,而在使用時指定類型的特性。
function useGeneric<T>(length: number,value: T):Array<T>{ let array: Array<T> = []; for(let i=0;i<length;i++){ array.push(value); } return array; } useGeneric<string>(2,'hello world'); useGeneric<number>(100,1);
裝飾器是特殊類型的聲明,能夠被附加到類聲明、方法、訪問符、屬性或參數上,具體文檔:
https://www.tslang.cn/docs/ha...
裝飾器並未成爲ES7的規範,所以將來可能會發生改變,並不推薦你們在線上項目中使用
function enumerable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { descriptor.enumerable = value; }; } class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @enumerable(false) greet() { return "Hello, " + this.greeting; } }
描述非TypeScript編寫的類庫的類型,須要聲明類庫所暴露出的API,相似於C的頭文件,在TypeScript中文件類型則爲 .d.ts