隨着應用的龐大,項目中 JavaScript 的代碼也會愈來愈臃腫,這時候許多 JavaScript 的語言弊端就會愈發明顯,而 TypeScript 的出現,就是着力於解決 JavaScript 語言天生的弱勢:靜態類型。html
前端開發 QQ 羣:377786580前端
這篇文章首發於個人我的博客 《據說》,系列目錄:vue
在上一篇文章 《從 JavaScript 到 TypeScript 1 - 什麼是 TypeScript》 中咱們討論了什麼是 TypeScript。這一篇文章咱們來介紹 TypeScript 一些基礎類型約束。node
咱們先簡單的聲明一些變量:typescript
let a: number let b = true // 有默認值的狀況,甚至不須要聲明類型,ts 會自動推導 let c: [string, number] // 元組 enum Color {Red, Green, Blue} // 枚舉 let d: { name: string } = { name: 'linkFly' }
當咱們給這些變量賦錯誤的類型值的時候,會拋出類型錯誤異常。express
是否是很簡單,TypeScript 優秀的設計使得即便你沒有接觸過它,可是仍然可以讀懂它。數組
// array let list_a: number[] = [1, 2, 3] let list_b: Array<number> = [1, 2, 3] // number 類型的數組 let list_c: [string, number] = ['linkFly', 0] // any let notSure: any = 4 notSure = true // any 類型能夠自由賦值 // 函數類型 let fn: (id: string) => number = (id) => 1 // 這裏使用了 ECMAScript 6 的箭頭函數,和下面的代碼等價 let fn: (id: string) => number = function (id) { return 1 }
// 聯合類型, foo 是 string 或 number let foo: string | number = 1 // 類型斷言,強制使用兼容類型中的某一類型 (foo as string) // 類型保護(判斷) if (typeof foo === 'string') { // dosomething } // 類型保護(判斷) if (foo instanceof String) { // dosomething }
從前幾年熱門的 MVC
一直到如今熱門的 MVVM
,咱們發現不管是 MVC(Model-View-Controller) 仍是 MVVM(Model-View-ViewModel),咱們始終拋不開一個關鍵的地方 —— 數據層:Model
。架構
由於本質上整個頁面的操做都是在進行數據流動,頁面展示本質上都是數據,而咱們經過 Model
來描述數據。ide
這是一個簡單的 Model
演示:函數
let user : { id: number, name: string } = { id: 1, name: 'linkFly' }
在 TypeScript (或者是全部強 OO 語言)中,推薦以 Model
來描述數據的方式也就是 Class
。
這一小節只簡單介紹 Class 和 泛型,實際項目中可能還會牽扯更多更強大的 OO 概念:接口、抽象類、繼承類、繼承屬性。
這些知識不是一蹴而就的,而是須要在項目中不斷探索不斷組合的。
全部類型的根本都是類,TS 中聲明一個類的語法很是簡單,可讀性很高。
注意,TS 中類型是核心,當你想把一個項目從 JavaScript 遷移到 TypeScript 的時候,須要爲項目中補充大量的類型,而這些類型大部分都是基於 Class
構建的。
這是一個簡單的類:
class User { id: number name: string } let user: User = { id: 1, name: 'linkFly' }
固然隨着需求的不一樣,也能夠補充不少細節:
class User { // 只讀屬性 readonly id: number // 存取器, get/set private _name: string get name(): string { // dosomething return this._name } set name (name: string) { console.log('this is set method') // dosomething this._name = name } // 構造函數 constructor (id: number, theName: string) { // 只讀屬性只能在構造函數裏初始化 this.id = id this._name = theName } // 實例方法 say () { console.log(`name: ${this.name}`) } // 靜態方法(類方法) static print () { console.log('static method') } } let user = new User(1, 'linkFly') user.name = 'tasaid' // 會輸出 'this is set method' user.say() // 實例方法 User.print() // 靜態方法
泛型是用來解決類型重用的問題。
例以下面一個函數,只能傳遞 number
的參數並返回:
function identity(arg: number): number { // dosomething return arg }
如今想傳遞一個 string
類型的參數,而後也返回它,這個時候就可使用泛型,使用泛型能夠接收任意類型並返回:
// 這個 T 就是泛型,也能夠叫其餘名字 function identity<T>(arg: T): T { // dosomething return arg } identity<string>('linkfly') identity('linkfly') // 自動推導 identity(0) identity(true)
咱們能夠輕鬆的使用泛型來實現數據包裝:
function fetch<T>(url: string): Promise<T> { // 遠程請求數據並返回結果 return fetch(url).then(data => { return data as T }) } class User { name: string } // 泛型使用 let user = fetch<User>('https://tasaid.com/user')
declare namespace Models { interface GPS { lat: number lng: number } }
這個系列的文章不會講解 TypeScript 的聲明文件,可是它是 TypeScript 中不可缺乏的一部分。
any
類型,它意味着類型不可控as
強制進行類型推導便可。window.tempName = 'linkFly' // Errors: [ts] Property 'tempName' does not exist on type 'Window'. // 強制推導 (window as any).tempName = 'linkFly'
至此,咱們對 TypeScript 類型、Model 已經有了必定的瞭解,在下一篇,咱們將瞭解如何引入和編譯 TypeScript:《從 JavaScript 到 TypeScript 3 - 引入和編譯》
TypeScript 中文網:https://tslang.cn/
TypeScript 視頻教程:《TypeScript 精通指南》