隨着應用的龐大,項目中 JavaScript 的代碼也會愈來愈臃腫,這時候許多 JavaScript 的語言弊端就會愈發明顯,而 TypeScript 的出現,就是着力於解決 JavaScript 語言天生的弱勢:靜態類型。javascript
前端開發 QQ 羣:377786580html
這篇文章首發於個人我的博客 《據說》,系列目錄:前端
幾個月前,團隊裏以爲不少項目跑的愈來愈臃腫,團隊協做遇到了一個很大的難題:如何讓一個別人提供的方法產出一個一目瞭然的文檔?由於一個項目總會涉及到多人協做:同窗 A 編寫了函數 a(),而 同窗 B 在調用函數 a() 的時候得一直擼着 API 文檔才能知道 a() 須要什麼參數,會返回什麼參數。vue
而 同窗 A 後續又改動了函數 a(),可是卻忘記了更新文檔,這時候新接手項目的 同窗 C 看着 API 文檔和函數 a() 一臉懵逼,問題浮出水面:團隊協做中,提供的接口如何描述自身?java
這其中涉及到的問題有:node
咱們意識到 JavaScript 在逐漸複雜的 Web 應用中缺乏一個很重要的東西:靜態類型。react
由於須要有靜態類型咱們才能夠知道這個函數須要的參數是什麼,有什麼類型,返回值是什麼類型,哪些字段是可能空,哪些字段又須要什麼樣的格式。git
咱們首先找到了業界融合於 JavaScript 的方案:Flow程序員
後來對比以後發現:github
其中第二點很重要,由於團隊成員對添加了 Flow 的 JavaScript 語法想當排斥,而我我的一樣以爲 Flow 侵入 JavaScript 太過強烈,不如 TypeScript 直接作語言超集好,雖然兩者出發點上沒有太大區別,但從設計思想上來講 TypeScript 更吸引人。
TypeScript 的定位是作靜態類型語言,而 Flow 的定位是類型檢查器。
畢竟寫着 Flow 的時候內心想的是我在寫 JavaScript,而寫 TypeScript 內心想的是我在寫 TypeScript :)。
TypeScript 簡稱 TS。TypeScript 是 JavaScript 的超集,就是在 JavaScript 上作了一層封裝,封裝出 TypeScript 的特性,固然最終代碼能夠編譯爲 JavaScript。
TypeScript 早期的目標是爲了讓習慣編寫強類型語言的後端程序員,可以快速的編寫出前端應用(微軟大法好),由於 JavaScript 沒有強數據類型,因此 TypeScript 提供了強數據類型,這是 TypeScript 的核心。
隨着項目工程愈來愈大,愈來愈多的前端意識到強類型的重要性,隨着 TypeScript 的逐漸完善,支持者愈來愈多,強類型的需求愈來愈強。於此同時, angular 2.x
這個領頭羊率先使用 AtScript
開闢了強類型戰場。
JavaScript 行至今日,靈活,動態讓它活躍在編程語言界一線。而靈活,動態使得它又十分神祕,只有運行才能獲得答案。類型的補充填充了 JavaScript 的缺點,從 TypeScript 編譯到 JavaScript,多了靜態類型檢查,而又保留了 JavaScript 的靈活動態。
簡單來講:動態代碼一時爽,重構全家火葬場。
TypeScript 憑藉 Microsoft 深厚的語言設計功底,設計的十分優雅和簡單易用,學習成本很是低。
上面咱們所說了,TypeScript 的核心就是靜態數據類型,咱們來簡單瞭解一下靜態數據類型和簡單的類型推導,TypeScript 是以 *.ts
做爲文件後綴的,咱們建立一個 demo.ts
文件,寫下這段代碼:
let num: number
從上面的代碼中,咱們能夠知道變量 num
是 number
類型的,若是咱們給 num
賦其餘類型的值,則會報錯:
是否是很簡單?是的,這就是 TypeScript 的核心。
咱們再來看看一個函數該如何表達:
const fetch = function (url: string): Promise { }
fetch()
函數接收一個 string
類型的參數 url
,返回一個 Promise
。
如下是一個 JavaScript 的函數,不看方法內的寫法咱們徹底不知道這個 API 會有哪些坑。
export const fetch = function (url, params, user) { // dosomething return http(options).then(data => { return new Returns(null, data) }).catch(err => { return new Returns(err, null) }) }
這是 TypeScript 的寫法:
export const fetch = function (url: string | object, params?: any, user?: User): Promise<object | Error> { // dosomething return http(options).then(data => { return data }).catch(err => { return err }) }
這個 TypeScript 包含了不少信息:
url
多是 string
或 object
類型params
是能夠不傳的,也能夠傳遞任何類型user
要求是 User
類型的,固然也是能夠不傳Promise
,Promise
的求值結果多是 object
,也有多是 Error
看到上面的信息後,咱們大概知道能夠這麼調用並處理 fetch
的返回結果:
let result = await fetch('https://tasaid.com', { id: 1 }) // fetch 可能會返回 Error if (result instanceof Error) { // 錯誤處理 }
是否是頗有意思?鵝妹子嚶!TypeScript 在說話,TypeScript 在讓代碼描述自身。
這就是靜態數據類型的意義。靜態類型在越複雜的應用中,需求越強烈。
這是 react
對於數據類型的約束:
import PropTypes from 'prop-types' component.propTypes = { optionalArray: PropTypes.array, optionalBool: PropTypes.bool, optionalFunc: PropTypes.func, requiredFunc: PropTypes.func.isRequired, }
這是 vue
對於數據類型的約束:
Vue.component('component', { props: { optionalArray: Array, optionalBool: Boolean, optionalFunc: Function, requiredFunc: { type: Function, required: true } } })
而引入了 TypeScript 以後,就會感覺到真正流暢的數據類型約束:
class Component { optionalArray?: Array<string> // string 類型的 數組 optionalBool?: boolean // 寫上 ? 號,就表示着這個屬性可能爲空 optionalFunc?: (foo: string, bar: number) => boolean // 函數的參數,返回值都一目瞭然 requiredFunc: () => void }
TypeScript 是 JavaScript 的超集,目標也是對齊 ECMAScript 的標準規範和提案對齊,最終 TypeScript 也是編譯爲 JavaScript。
同時,和 JavaScript 規範標準 ECMAScript 提案 相比,TypeScript 也一直在跟進 ECMAScript 的許多新特性。
例如當前來講比較深受你們喜好的新特性:
而這些均可以編譯到 ECMAScript 3
(少數細節存在兼容性問題)。
types
文件夾中。或者在 @didi/*
倉庫名下能夠找到babel
是將高級版本的 JavaScript 編譯爲目標版本的 JavaScript,TypeScript
是將 TypeScript 編譯爲目標版本的 JavaScript。它們的編譯是重疊的,也就是說 TypeScript
能夠再也不依賴 babel
編譯。下一篇:《從 JavaScript 到 TypeScript 2 - 基礎特性和類型推導》
TypeScript 中文網:https://tslang.cn/
TypeScript 視頻教程:《TypeScript 精通指南》