JavaScript 到 TypeScript 1 - 什麼是 TypeScript

隨着應用的龐大,項目中 JavaScript 的代碼也會愈來愈臃腫,這時候許多 JavaScript 的語言弊端就會愈發明顯,而 TypeScript 的出現,就是着力於解決 JavaScript 語言天生的弱勢:靜態類型。javascript

前端開發 QQ 羣:377786580html

這篇文章首發於個人我的博客 《據說》,系列目錄:前端

爲何選擇 TypeScript

幾個月前,團隊裏以爲不少項目跑的愈來愈臃腫,團隊協做遇到了一個很大的難題:如何讓一個別人提供的方法產出一個一目瞭然的文檔?由於一個項目總會涉及到多人協做:同窗 A 編寫了函數 a(),而 同窗 B 在調用函數 a() 的時候得一直擼着 API 文檔才能知道 a() 須要什麼參數,會返回什麼參數。vue

同窗 A 後續又改動了函數 a(),可是卻忘記了更新文檔,這時候新接手項目的 同窗 C 看着 API 文檔和函數 a() 一臉懵逼,問題浮出水面:團隊協做中,提供的接口如何描述自身?java

這其中涉及到的問題有:node

  1. 接口如何描述本身的參數和返回值?
  2. 接口參數和返回值在無數需求迭代中改變了屢次,而這個 API 對應的文檔該如何更新?
  3. 數據格式如何描述

咱們意識到 JavaScript 在逐漸複雜的 Web 應用中缺乏一個很重要的東西:靜態類型。react

由於須要有靜態類型咱們才能夠知道這個函數須要的參數是什麼,有什麼類型,返回值是什麼類型,哪些字段是可能空,哪些字段又須要什麼樣的格式。git

咱們首先找到了業界融合於 JavaScript 的方案:Flow程序員

後來對比以後發現:github

  1. 生態圈,TypeScript 的生態圈明顯在 Flow 之上,各大主流類庫都提供了 TypeScript 的類型聲明文件,配合 visual studio code 編碼體驗上比 Flow 強太多。
  2. Flow 是侵入 JavaScript 的,對 JavaScript 作了一層加強;而 TypeScript 則爲 JavaScript 超集,在 JavaScript 之上進行的語言抽象,最終編譯成 JavaScript。

其中第二點很重要,由於團隊成員對添加了 Flow 的 JavaScript 語法想當排斥,而我我的一樣以爲 Flow 侵入 JavaScript 太過強烈,不如 TypeScript 直接作語言超集好,雖然兩者出發點上沒有太大區別,但從設計思想上來講 TypeScript 更吸引人。

TypeScript 的定位是作靜態類型語言,而 Flow 的定位是類型檢查器。

畢竟寫着 Flow 的時候內心想的是我在寫 JavaScript,而寫 TypeScript 內心想的是我在寫 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

從上面的代碼中,咱們能夠知道變量 numnumber 類型的,若是咱們給 num 賦其餘類型的值,則會報錯:

clipboard.png

是否是很簡單?是的,這就是 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 包含了不少信息:

  1. url 多是 stringobject 類型
  2. params 是能夠不傳的,也能夠傳遞任何類型
  3. user 要求是 User 類型的,固然也是能夠不傳
  4. 返回了一個 PromisePromise 的求值結果多是 object,也有多是 Error

看到上面的信息後,咱們大概知道能夠這麼調用並處理 fetch 的返回結果:

let result = await fetch('https://tasaid.com', { id: 1 })

// fetch 可能會返回 Error
if (result instanceof Error) {
  // 錯誤處理
}

是否是頗有意思?鵝妹子嚶!TypeScript 在說話,TypeScript 在讓代碼描述自身。

clipboard.png

這就是靜態數據類型的意義。靜態類型在越複雜的應用中,需求越強烈。

這是 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 
}

和 ECMAScript 相比

TypeScript 是 JavaScript 的超集,目標也是對齊 ECMAScript 的標準規範和提案對齊,最終 TypeScript 也是編譯爲 JavaScript。

同時,和 JavaScript 規範標準 ECMAScript 提案 相比,TypeScript 也一直在跟進 ECMAScript 的許多新特性。

例如當前來講比較深受你們喜好的新特性:

  • import() 動態表達式
  • decorators 裝飾器
  • async/await 異步

而這些均可以編譯到 ECMAScript 3(少數細節存在兼容性問題)。

小 tips

  • 使用 visual studio code 編輯器會體驗到 TypeScript 強大的類型推導,畢竟兩個都是微軟親兒子
  • 一些 JavaScript 編寫的大型的第三方庫,都提供了 TypeScript 的類型聲明文件(*.d.ts 文件), 通常都放在包目錄的 types 文件夾中。或者在 @didi/* 倉庫名下能夠找到
  • babel 是將高級版本的 JavaScript 編譯爲目標版本的 JavaScript,TypeScript 是將 TypeScript 編譯爲目標版本的 JavaScript。它們的編譯是重疊的,也就是說 TypeScript 能夠再也不依賴 babel 編譯。

下一篇:《從 JavaScript 到 TypeScript 2 - 基礎特性和類型推導

 

TypeScript 中文網:https://tslang.cn/

TypeScript 視頻教程:《TypeScript 精通指南

相關文章
相關標籤/搜索