TypeScript體系調研報告

做者簡介:aoto 螞蟻金服·數據體驗技術團隊javascript

Q:爲何要寫這邊文章?這篇文章要表達什麼?html

A:咱們考慮在SPA應用中使用TS做爲開發語言,咱們須要一篇系統性介紹TS自己及周邊的文章來論證在項目中使用TS做爲開發語言是科學合理的,並且是順勢而爲的。前端

導引

  • TS是什麼
  • 爲何要用TS
  • TS能幹點什麼
  • 使用TS的成本
  • 社區發展
  • 周邊生態
  • 深刻解讀TS
  • 接受TS
  • 權衡

TS是什麼

TypeScript

TypeScript = Type + Script(標準JS)。咱們從TS的官方網站上就能看到定義:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript。TypeScript是一個編譯到純JS的有類型定義的JS超集。java

爲何要用TS

目標:生命週期較長(經常持續幾年)的複雜SPA應用,保障開發效率的同時提高代碼的可維護性和線上運行時質量。react

  • 從開發效率上看,雖然須要多寫一些類型定義代碼,但TS在VSCode、WebStorm等IDE下能夠作到智能提示,智能感知bug,同時咱們項目經常使用的一些第三方類庫框架都有TS類型聲明,咱們也能夠給那些沒有TS類型聲明的穩定模塊寫聲明文件,如咱們的前端KOP框架(目前仍是螞蟻內部框架,類比dva),這在團隊協做項目中能夠提高總體的開發效率。
  • 從可維護性上看,長期迭代維護的項目開發和維護的成員會有不少,團隊成員水平會有差別,而軟件具備的特質,長期迭代維護的項目總會遇到可維護性逐漸下降的問題,有了強類型約束和靜態檢查,以及智能IDE的幫助下,能夠下降軟件腐化的速度,提高可維護性,且在重構時,強類型和靜態類型檢查會幫上大忙,甚至有了類型定義,會不經意間增長重構的頻率(更安全、放心)。
  • 從線上運行時質量上看,咱們如今的SPA項目的不少bug都是因爲一些調用方和被調用方(如組件模塊間的協做、接口或函數的調用)的數據格式不匹配引發的,因爲TS有編譯期的靜態檢查,讓咱們的bug儘量消滅在編譯器,加上IDE有智能糾錯,編碼時就能提早感知bug的存在,咱們的線上運行時質量會更爲穩定可控。

一個複雜軟件的常規研發流程,大體分爲定義問題、需求分析、規劃構建、軟件架構、詳細設計、編碼調試、單元測試、集成測試、集成、系統測試、保障維護。構建活動(主要是編碼調試)在中大型項目中的工做量佔比大於50%。同時,一箇中大型項目,bug由構建階段引發的比例佔到50%~75%,對於一個成功的項目來講,構建活動是必需要作的,並且是工程師更爲可控的。【代碼大全】webpack

TS適合大規模JavaScript應用,正如他的官方宣傳語JavaScript that scales。從如下幾點能夠看到TS在團隊協做、可維護性、易讀性、穩定性(編譯期提早暴露bug)等方面上有着明顯的好處:git

  • 加上了類型系統,對於閱讀代碼的人和編譯器都是友好的。對閱讀者來講,類型定義加上IDE的智能提示,加強了代碼的易讀型;對於編譯器來講,類型定義可讓編譯器揪出隱藏的bug。
  • 類型系統+靜態分析檢查+智能感知/提示,使大規模的應用代碼質量更高,運行時bug更少,更方便維護。
  • 有相似VSCode這樣配套的IDE支持,方便的查看類型推斷和引用關係,能夠更方便和安全的進行重構,不再用全局搜索,一個個修改了。
  • 給應用配置、應用狀態、先後端接口及各類模塊定義類型,整個應用都是一個個的類型定義,使協做更爲方便、高效和安全。

TS能幹點什麼

靜態檢查

這類問題是ESLint等工具檢測不出來的。程序員

低級錯誤

const peoples = [{
  name: 'tim',
  age: 20
}, {
  name: 'alex',
  age: 22
}];
const sortedPeoples = peoples.sort((a, b) => a.name.localCompare(b.name));

執行TS編譯命令tsc,檢測到錯誤:github

error TS2339: Property 'localCompare' does not exist on type 'string'.

若是是在支持TS的IDE中(VS Code、WebStorm等),則不需等到編譯,在IDE中就能夠很是明顯在localCompare位置提示出錯誤信息。web

localCompare這種輸入手誤(或者手滑不當心刪除或添加了字符)時有發生,若是沒有編譯器靜態檢查,那有可能就是一個字符引起的血案:埋下了一個隱藏的運行時bug。若是在SPA應用中,這個問題須要較長的操做路徑才能被發現,一旦用戶觸發這個地雷,那它就會爆炸:應用直接crash(在沒有頁面刷新的SPA中問題尤其凸顯)。

非空判斷

let data = {
  list: null,
  success: true
};
const value = data.list.length;

執行tsc編譯:

error TS2532: Object is possibly 'null'.

data.list.length這行直接引用了data.list的屬性,但data.list的數據格式有不是數組的可能性,這種場景在前端處理後端接口返回時常常出現,接口返回的數據層級可能很是深,若是在某一級缺乏了非空判斷邏輯,那就意味着埋下了一個不知道何時就會引爆的炸彈。

類型推斷

const arr = [];
arr.toUpperCase();

class Cat {
  miao() {}
}

class Dog {
  wang() {}
}
const cat = new Cat();
cat.wang();

執行tsc編譯:

error TS2339: Property 'toUpperCase' does not exist on type 'any[]'.
error TS2339: Property 'wang' does not exist on type 'Cat'.

TS有類型推斷,給不一樣類型的執行對象調用錯誤的方法都將被檢查出來。

面向對象編程加強

訪問權限控制

class Person {
  protected name: string;
  public age: number;
  constructor(name: string) { this.name = name; }
}

class Employee extends Person {
  static someAttr = 1;
  private department: string;

  constructor(name: string, department: string) {
    super(name);
    this.department = department;
  }
}
let howard = new Employee("Howard", "Sales");
console.log(howard.name);

執行tsc編譯:

error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses.

Person中name屬性是protected類型,只能在本身類中或者子類中使用。訪問權限控制在面向對象編程中頗有用,他能幫忙咱們作到信息隱藏,JS面向對象編程的一個大問題就是沒有提供原生支持信息隱藏的方案(不少時候都是經過約定編碼方式來作)。信息隱藏有助於更好的管理系統的複雜度,這在軟件工程中顯得尤其重要。

接口

interface Machine {
  move(): void
}

interface Human {
  run(): void
}

class Base {
}

class Robot extends Base implements Machine, Human {
  run() {
    console.log('run');
  }
  move() {
    console.log('move');
  }
}

Robot類能夠繼承Base類,並實現Machine和Human接口,這種能夠組合繼承類和實現接口的方式使面向對象編程更爲靈活、可擴展性更好。

泛型

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

定義了一個模板類型T,實例化GenericNumber類時能夠傳入內置類型或者自定義類型。泛型(模板)在傳統面向對象編程語言中是很常見的概念了,在代碼邏輯是通用模式化的,參數能夠是動態類型的場景下比較有用。

類型系統

interface SystemConfig {
  attr1: number;
  attr2: string;
  func1(): string;
}

interface ModuleType {
  data: {
    attr1?: string,
    attr2?: number
  },
  visible: boolean
}

const config: SystemConfig = {
  attr1: 1,
  attr2: 'str',
  func1: () => ''
};

const mod: ModuleType = {
  data: {
    attr1: '1'
  },
  visible: true
};

咱們定義了一個系統配置類型SystemConfig和一個模塊類型ModuleType,咱們在使用這些類型時就不能隨便修改configmod的數據了。每一個被調用方負責本身的對外類型展示,調用者只需關心被調用方的類型,不需關心內部細節,這就是類型約束的好處,這對於多人協做的團隊項目很是有幫助。

模塊系統加強

namespace N {
  export namespace NN {
    export function a() {
      console.log('N.a');
    }
  }
}

N.NN.a();

TS除了支持ES6的模塊系統以外,還支持命名空間。這在管理複雜模塊的內部時比較有用。

使用TS的成本

學習成本

理論上學習並應用一門新語言是須要很高成本的,但好在TS自己是JS的超集,這也意味着他自己是能夠支持現有JS代碼的,至少理論上是這樣。學習一下類型系統的相關知識和麪向對象的基礎知識,應該能夠hold住TS,成本不會很高。官方文檔是最好的學習材料。

應用成本

老項目

對於老項目,因爲TS兼容ES規範,因此能夠比較方便的升級現有的JS(這裏指ES6及以上)代碼,逐漸的加類型註解,漸進式加強代碼健壯性。遷移過程:

  1. npm全局安裝typescript包,並在工程根目錄運行tsc --init,自動產生tsconfig.json文件。
    默認的3個配置項:更多配置項說明
    • "target":"es5": 編譯後代碼的ES版本,還有es3,es2105等選項。
    • "module":"commonjs":編譯後代碼的模塊化組織方式,還有amd,umd,es2015等選項。
    • "strict":true:嚴格校驗,包含不能有沒意義的any,null校驗等選項。
  2. 初始化獲得的tsconfig.json無需修改,增長"allowJs": true選項。
  3. 配置webpack配置,增長ts的loader,如awesome-typescript-loader。(若是是基於atool-build來構建的項目,則它內置了ts編譯,這步省略)
    json loaders: [ // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. { test: /\.tsx?$/, loader: "awesome-typescript-loader" } ]

  4. 此時你能夠寫文件名爲ts和tsx(React)後綴的代碼了,它能夠和現有的ES6代碼共存,VSCode會自動校驗這部分代碼,webpack打包也沒問題了。
  5. 逐漸的,開始打算重構之前的ES6代碼爲TS代碼,只需將文件後綴改爲ts(x)就行,就能夠享受TS及IDE智能感知/糾錯帶來的好處。

更多遷移教程:官方遷移教程官方React項目遷移教程社區教程1社區教程2

新項目

  • 對於新項目,微軟提供了很是棒的一些Starter項目,詳細介紹瞭如何用TS和其餘框架、庫配合使用。若是是React項目,能夠參考這個Starter:TypeScript-React-Starter

成本對比

星多表示佔優

成本點 ES TS 說明
學習和踩坑成本 ※※※※※ ※※※ 雖然是JS超集,但仍是要學習TS自己及面向對象基礎知識,開發環境搭建、使用中的問題和坑也須要本身趟,好在TS社區比較成熟,網上沉澱的資料不少
總體代碼量 ※※※※※ ※※※※ TS代碼增長比較完善的類型定義的話總體代碼量比原生ES多5%~10%左右
原生JS(標準ES、瀏覽器端、服務器端) ※※※ ※※※※※ IDE內置了詳盡的類型聲明,能夠智能提示方法和參數說明,提高了效率
依賴外部庫(React、Lodash、Antd) ※※※ ※※※※※ 有TS類型聲明庫,IDE智能提示和分析,效率提高
內部公共庫、模塊 ※※※ ※※※※ 團隊內部自行編寫類型定義文件,有必定工做量,但開發效率能夠有一些提高,逐步完善類型定義後,效率進一步提高
團隊協做效率 ※※ ※※※※※ 對系統配置、外部接口、內部模塊作類型定義後,實例對象屬性就不能隨意改了,每一個被調用方負責本身的對外類型展示(能夠理解爲形狀),調用者只需關心被調用方的類型,不需關心內部細節
代碼可維護性 ※※ ※※※※ 因爲團隊成員水平差別,和軟件的的特質,長期迭代維護的項目總會遇到可維護性的問題,有了強類型約束和靜態檢查,以及智能IDE的幫助下,能夠下降軟件腐化的速度,提高可維護性,且在重構時,強類型和靜態類型檢查會幫上大忙,甚至有了類型定義,會不經意間增長重構的頻率
運行時穩定性 ※※ ※※※※ 因爲TS有靜態類型檢查,不少bug都會被消滅在上線前

小結

從上面的對比中能夠看到,使用你們都熟悉的ES做爲開發語言只在學習和踩坑成本以及總體代碼量上佔優,若是隻是短時間項目,那用ES無可厚非,但咱們的項目生命週期持續好幾年,是持續迭代升級的,目前TS社區已經比較成熟,學習資料也不少,並且TS帶來的是內部協做開發效率、可維護性、穩定性的提高,因此從長遠來看這個代價是值得付出的。並且各類類型聲明定義文件的存在,是能夠提高開發效率的;並且靜態類型檢查能夠減小bug數量和排查bug的難度,變相也提高了效率,並且使整個項目相對變得更爲穩定可控。

社區發展

從Stackoverflow的2017年開發者調查報告Google趨勢npm下載量趨勢上能夠到看,TypeScript社區發展很快,特別是最近幾年。特別是伴隨着VS Code的誕生(TS寫的,對TS支持很是友好),VS Code + TypeScript的組合讓前端圈產生了一股清流,生產力和規範性獲得了快速提高。從Google對TS的支持(Angular高於2的版本是TS寫的)看到,國際大廠也是支持的。

從螞蟻集團內部看,Ant Design、Basement等產品也是基於TS寫的(至少是在大量使用),雖然有一些反對的聲音,但整體仍是看好的,有合適的土壤就會快速發展,如Ant Design。

周邊生態

類型聲明包

React、及其餘各類著名框架、庫都有TS類型聲明,咱們能夠在項目中經過npm install @types/react方式安裝,能夠在這個網站搜索你想要安裝的庫聲明包。安裝後,寫和那些框架、庫相關的代碼將會是一種很是爽的體驗,函數的定義和註釋將會自動提示出來,開發效率將會獲得提高。

IDE

VS Code、WebStorm等前端圈流行的IDE都對TS有着很是友好的支持,VS Code甚至自身就是TS寫成的。

深刻解讀TS

TS語言設計目標

目標

編譯期能夠作靜態檢查,爲大規模代碼提供結構化裝置,編譯出符合習慣、易讀的JS代碼,和ECMAScript標準對齊,使用一向的、可刪除的、結構化的類型系統,保護編譯後的JS代碼的運行時行爲等等。

非目標

模仿現有語言,優化編譯後代碼的性能,應用「正確」的類型系統,增長運行時類型信息等等。

TS設計目標原文

TS簡史

在最近幾年,隨着V8平臺、各大現代瀏覽器的起來,JS的運行平臺再不斷完善,但,JS對於大型應用的開發是很是困難的,JS語言設計出來的目的不是爲了大型應用,他是一門腳本語言,他沒有靜態類型校驗,但更重要的是,他沒有提供大型應用必須的classes、modules/namespaces、interfaces等結構化的裝置,中間也出來過GWT等爲了其餘語言開發者開發大型JS應用的項目,這些項目可讓你利用Java等面嚮對象語言開發大型Web應用,也能夠利用到Eclipse等好用的IDE,但這些項目不是用JS寫代碼,因此若是你想用JS裏的一些東西,你可能要比較費勁的在其餘語言裏把它給實現出來,因此咱們考慮如何加強JS語言,提供如靜態類型檢查、classes、modules/namespaces、interfaces等大型應用裝置,這就是TS語言:TS是一種開發大型JS應用的語言,更詳細一點來講,TS是有類型的編譯到純JS的JS超集。因此通常來講,JS代碼也是TS代碼。自己TS編譯器也是TS寫的,運行Node.js環境。【Anders Hejlsberg: Introducing TypeScript 2012

TS做者在最近微軟Build大會給出的一個圖:

JS feature間隔

如圖,Web和Node平臺的JS始終與JS最新規範有一段距離,Web平臺的距離更遠,TS能夠填充這個間隙,讓使用者在Web和Node平臺都能用上最新的Feature,用上優雅的JS,提升生產力。【Anders Hejlsberg: What's new in TypeScript? 2017

和Flow 、Babel的對比

vs Flow

這篇文章能夠看出,基礎的類型檢查功能發展到如今已經差異不大了,但在周邊生態、文檔完整性、社區資源方面TS賽過Flow。

vs Babel

Babel也是很不錯的ES6 to 5編譯工具,有不錯的插件機制,社區發展也不錯,但在一樣一段代碼編譯出的JS代碼裏能夠看到,TS編譯後的代碼是更符合習慣、簡潔易讀一些(都用的是官方網站的Playground工具)。我曾經維護過TS編譯後的JS代碼(TS源碼丟失),感受還OK。

Babel編譯後:
Babel編譯

TS編譯後:
TS編譯

TS基礎知識及核心概念

基礎類型

let isDone: boolean = false;

let decimal: number = 6;

let color: string = "blue";

// 數組,有兩種寫法
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

// 元組(Tuple)
let x: [string, number] = ["hello", 10];

// 枚舉
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

// 不肯定的能夠先聲明爲any
let notSure: any = 4;

// 聲明沒有返回值
function warnUser(): void {
    alert("This is my warning message");
}

let u: undefined = undefined;

let n: null = null;

// 類型永遠沒返回
function error(message: string): never {
    throw new Error(message);
}

// 類型主張,就是知道的比編譯器多,主動告訴編譯器更多信息,有兩種寫法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;

更多介紹能夠直接看官方文檔

interface

TS中的一個核心原則之一就是類型檢查關注的是值的形狀,有時就叫作「鴨子辨型」(duck typing)或「結構化子類型」(structural subtyping)。TS中interface就承擔了這樣的角色,定義形狀與約束,在內部使用或者和外部系統協做。一個例子:

interface SystemConfig {
    attr1: string;
    attr2: number;
    func1(): string;
    func2(): void;
}

咱們給軟件定了一個系統參數的配置接口,他定義了系統配置的形狀,有兩個屬性attr1attr2,兩個方法func1func2,這樣若是定義了const systemConfig: SystemConfig = {},那systemConfig就不能隨意修改了,他有形狀了。

在Java中,咱們提倡面向接口編程,接口優於抽象類【Effective Java】,在TS的類系統中,接口也能夠承擔這樣的角色,咱們能夠用implements來實現接口,這樣能夠實現相似更爲靈活的繼承,如:

class A extends BaseClass implements BaseInterface1, BaseInterface2 {}

類A繼承了BaseClass,而且繼承了BaseInterface1和BaseInterface2兩個接口。

module/namespace

導出到外部的模塊寫法和ES6同樣,內部模塊如今推薦用namespace,如:

namespace Module1 {
  export interface SubModule1 {}

  export interface SubModule2 {}
}
const module: Module1.SubModule = {}

命名空間在JS中用對象字面量也能夠實現,早些年的不少JS庫都是這種模式,但顯然有了這種顯示的命名空間聲明,代碼的易讀性更好,且不能隨意的改變,不像用原生JS對象時容易被覆蓋。

訪問權限控制

TS有着和傳統面嚮對象語言相似的public、protected、private等訪問權限,這個在大型應用中很實用,這裏不展開。

其餘

除了泛型相對難以掌握,其餘class、decorator、async/await等都和ES六、ES7寫法相似。

Type和Type System

TypeScript = Type + Script,那麼編程語言中的Type是怎麼定義的呢?

In computer science and computer programming, a data type or simply type is a classification of data which tells the compiler or interpreter how the programmer intends to use the data.【維基百科

在計算機科學中,數據類型或者簡單說類型,是數據的類別,用來告訴編譯器/解釋器程序員想怎麼使用數據。基本的數據類型如整數、布爾值、字符等,組合數據類型如數組、對象等,也有抽象數據類型如隊列、棧、集合、字典等等。數據類型用在類型系統中,類型系統提供了類型定義、實現和使用的方式,每種編程語言都有各自的類型系統實現(若是有的話)。

咱們來看看Type System(類型系統)的定義:

In programming languages, a type system is a set of rules that assigns a property called type to the various constructs of a computer program, such as variables, expressions, functions or modules.[1] These types formalize and enforce the (otherwise implicit) categories the programmer uses for data structures and components (ex: "string", "array of float", "function returning boolean"). The main purpose of a type system is to reduce possibilities for bugs in computer programs[2] by defining interfaces between different parts of a computer program, and then checking that the parts have been connected in a consistent way. 【維基百科

在編程語言中,類型系統是一個規則集合,給程序中的變量、表達式、函數、模塊等程序構建元素分配叫作類型的屬性。這些類型明確並強制(也多是含蓄的)程序員如何使用數據結構。類型系統的主要目的是經過定義程序不一樣部分間協做的接口,並檢查不一樣部分以始終如一的方式協做,來減小程序可能產生的bug。這種檢查多是靜態的(編譯期)或動態的(運行時),或者既有靜態的也有動態的。

類型系統的好處

檢測錯誤

The most obvious benefit of static typechecking is that it allows early detection of some programming errors. Errors that are detected early can be fixed immediately, rather than lurking in the code to be discovered much later,when the programmer is in the middle of something else—or even after the program has been deployed. Moreover, errors can often be pinpointed more accurately during typechecking than at run time, when their effects may not become visible until some time after things begin to go wrong.【Types and Programming Languages

As your app grows, you can catch a lot of bugs with typechecking. 【React typechecking

靜態類型檢查最明顯的好處是能夠儘早的檢查出程序中的錯誤。錯誤被儘早的檢查出來可使它獲得快速的修復,而不是潛伏在代碼中,在中期甚至部署上線後才被發現。並且,錯誤在編譯期能夠被更精確的定位出來,而在運行時,錯誤產生的影響在程序出現問題前多是不容易被發現的。

程序會有各類各樣的數據結構,若是改了一個數據類型,前端不少時候都是經過全局查找來處理這種重構問題的。而靜態類型檢查則可使再次編譯後就能探知全部可能的錯誤,加上IDE的智能錯誤提示,重構起來更放心、更方便。

抽象化

Another important way in which type systems support the programming process is by enforcing disciplined programming. In particular, in the context of large-scale software composition, type systems form the backbone of the module languages used to package and tie together the components of large systems. Types show up in the interfaces of modules (and related structures such as classes); indeed, an interface itself can be viewed as 「the type of a module,」 providing a summary of the facilities provided by the module—a kind of partial contract between implementors and users.

Structuring large systems in terms of modules with clear interfaces leads to a more abstract style of design, where interfaces are designed and discussed independently from their eventual implementations. More abstract thinking about interfaces generally leads to better design.【Types and Programming Languages

類型系統支持編程階段的另一個重要方式是強制讓編程遵照紀律。在大規模軟件系統中,類型系統組成了組件協做系統的脊樑。類型展示在模塊(或者相關的結構如類)的接口中。接口能夠看作「模塊的類型」,展現了模塊所能提供的功能,是一種實現者和用戶間的合約。

在大量模塊協做組成的大規模結構化軟件系統中清晰的接口可使設計更爲抽象,接口的設計和討論獨立於它們的實現。通常來講,對接口更爲抽象的思考可使得作出更好的設計。

Types enable programmers to think at a higher level than the bit or byte, not bothering with low-level implementation. For example, programmers can begin to think of a string as a set of character values instead of as a mere array of bytes. Higher still, types enable programmers to think about and express interfaces between two of any-sized subsystems. This enables more levels of localization so that the definitions required for interoperability of the subsystems remain consistent when those two subsystems communicate.【維基百科

類型會讓程序員在一個更高的維度思考,而不是在底層的計算機實現細節糾纏。例如,咱們能夠把字符串想成字符集,而不只僅是比特數組。更高維度,類型系統可讓咱們用接口來思考和表達任意子系統/子程序之間的協做,接口定義可讓子系統/子程序之間的通訊方式始終如一。

文檔化

Types are also useful when reading programs. The type declarations in procedure headers and module interfaces constitute a form of documentation,giving useful hints about behavior. Moreover, unlike descriptions embedded in comments, this form of documentation cannot become outdated, since it
is checked during every run of the compiler. This role of types is particularly important in module signatures.【Types and Programming Languages

類型對於閱讀程序也是有用的。在程序頭部的類型聲明和模塊接口造成了文檔的形狀,提供程序的行爲提示。此外,不一樣於在註釋中的描述,這種形式的文檔不會過時,由於每次編譯都會校驗,這在模塊簽名裏特別重要。

In more expressive type systems, types can serve as a form of documentation clarifying the intent of the programmer. For example, if a programmer declares a function as returning a timestamp type, this documents the function when the timestamp type can be explicitly declared deeper in the code to be an integer type.【維基百科

在複用表現力的類型系統中,類型能夠看作是一種描述程序員意圖的表述方式。例如,咱們聲明一個函數返回一個時間戳,這樣就至關於明確說明了這個函數在更深層次的代碼調用中會返回整數類型。

語言安全

The term 「safe language」 is, unfortunately, even more contentious than 「type system.」 Although people generally feel they know one when they see it, their notions of exactly what constitutes language safety are strongly influenced by the language community to which they belong. Informally, though, safe
languages can be defined as ones that make it impossible to shoot yourself in the foot while programming.【Types and Programming Languages

安全語言這個說法是有爭議的。受到該語言社區的嚴重影響。不正式的來講,安全語言能夠被定義爲在編程時不可能從底層把本身殺死。

A type system enables the compiler to detect meaningless or probably invalid code. For example, we can identify an expression 3 / "Hello, World" as invalid, when the rules do not specify how to divide an integer by a string. Strong typing offers more safety, but cannot guarantee complete type safety.【維基百科

類型系統會容許編譯器檢查無心義或者可能不合法的代碼。例如,咱們知道3/'hello world'不合法,強類型提供了更多的安全性,但也不能徹底作到類型安全。

效率

Static type-checking may provide useful compile-time information. For example, if a type requires that a value must align in memory at a multiple of four bytes, the compiler may be able to use more efficient machine instructions.【維基百科

靜態類型檢查會提供有用的編譯期信息。例如,若是一個類型須要在內存中佔四個字節,編譯器可能會使用更有效率的機器指令。

靜態類型、動態類型和弱類型、強類型

  • 靜態類型:編譯期就知道每個變量的類型。類型錯誤編譯失敗是語法問題。如Java、C++。
  • 動態類型:編譯期不知道類型,運行時才知道。類型錯誤拋出異常發生在運行時。如JS、Python。
  • 弱類型:容忍隱式類型轉換。如JS,1+'1'='11',數字型轉成了字符型。
  • 強類型:不容忍隱式類型轉換。如Python,1+'1'會拋出TypeError

接受TS

TS剛出來時我是有點抵觸的,或者對她的感受就跟和CoffeeScriptDart等編譯到JS語言差很少,感受就是其餘語言往JS滲透的產物,近一兩年,社區中TS的聲音愈來愈強,而我也開始作大型JavaScript應用,隨之逐漸從新認識TS,逐漸認識到TS的類型系統、TSC的靜態檢查、VS Code等IDE的強力支持對於開發出可維護性好、穩定性高的大型JavaScript應用的重要性。

權衡

如何更好的利用JS的動態性和TS的靜態特質,咱們須要結合項目的實際狀況來進行綜合判斷。一些建議:

  • 若是是中小型項目,且生命週期不是很長,那就直接用JS吧,不要被TS束縛住了手腳。
  • 若是是大型應用,且生命週期比較長,那建議試試TS。開源項目如VS CodeGitHub桌面端,不開源的如Slack桌面端AsanaPalantir
  • 若是是框架、庫之類的公共模塊,那更建議用TS了。如Ant DesignAngularIonic

至於到底用不用TS,仍是要看實際項目規模、項目生命週期、團隊規模、團隊成員狀況等實際狀況綜合考慮。

原文地址

相關文章
相關標籤/搜索