9102年,隔壁公司新來的女實習生問我什麼是TypeScript ?

clipboard.png

TypeScript不是一個高深的技術,它不過是一個 javascript的超集,那麼什麼是超集呢?

clipboard.png

所謂的超集 其實就是最終將你寫的TypeScript編譯成javascript去執行,由於瀏覽器上能跑的腳本語言是javascript,這個本質要搞清楚javascript

傳統的Javascript 缺點:

1.弱類型,不嚴謹

沒法在編寫時察覺出同一個變量的類型是否保持一致html

好比:前端

var a = 1 

//若是這個b的值是「1」,字符串
var b = "1"

console.log(a+b)

結果:java

clipboard.png

2.不依賴插件,沒法感知編碼書寫是否出現邊際錯誤(出現某一瞬間空值等)

特別是ES6以前存在全局變量,var會給全局狀態下添加屬性以及污染全局加上ES5的變量提高做用域等混合狀況,很容易致使變量查找時出現undefined的問題,可是這個問題須要代碼運行才能報錯react

例如:webpack

var a;

    function test() {
        a = 1
    }
    
    console.log(a) //undefined
    console.log(window.a)//undefined
 
    
    -------------------
    
    
    var a;

    function test() {
        a = 1
    }

    test()

     console.log(a)    // 1 
     console.log(window.a) //1
像上面這種狀況,若是遇到了,項目很大,排查起來仍是很煩的

3.不依賴插件,沒有靜態類型以及上下文檢查

特別是在書寫Node.js的時候,每每這種偏後臺類型的代碼,高併發場景出現一個小問題都是致命的,若是是一個超大型項目,排查問題起來很是困難es6

傳統的javascriptweb

clipboard.png

這段代碼,變量a根本就沒有定義,可是根本沒有報錯,這種場景能夠在項目中多是右查詢沒有查詢到,而後輸出undefined. 但是若是是在使用這個變量去作某些事情typescript

例如: npm

這個a變量是一個用戶很核心的數據,可是它是undefined。而後又通過若干的類型轉換,被js轉換成不知道是什麼的數據展現給了客戶,那麼炸了,可能會引發整個項目出現致命性錯誤直接奔潰

4. 大型項目,多人合做,若是出了BUG每每可能要浪費你們不少時間(摸魚時間)

例如 :

你的同事A寫了一個模塊,大概5個文件,一共1000行代碼

通過1000行代碼的處理,最終輸出好幾個值(變量)給了你

以下代碼:

export default {
    store,
    checkPassWord,
    applyMiddleWare,
    //....
}

一個不合格的同事 給你的沒有註釋的代碼 因而你 :

clipboard.png

一個合格的同事:

/**
   @params store //數據對象
   @params checkPassWord //檢查密碼函數
   @params applyMiddleWare //應用中間間

*/
export default {
    store,
    checkPassWord,
    applyMiddleWare,
    //....
}

若是你用到他的暴露對象內容特別多的時候,就要一個一個去看註釋,並且關鍵是:

這裏面每一個函數的傳入參數,返回的參數,註釋不必定那麼完整詳細。

那麼只有去溝通了,一旦溝通起來。時間成本上升,而且若是你們開發任務都特別緊急的時候,炸了~

clipboard.png

因而,TypeScript出現了

TypeScript 3.1 現已發佈

最新版本文檔地址 最新TypeScript版本文檔地址

TypeScript並不能說是一門徹底全新的語言,能夠說它是一個基於javaScipt的超集

什麼是超集? 其實就是原生ES6語法+Type類型

強烈建議閱讀阮一峯老師的 ES6入門

咱們來看下 TypeScript的工做方式:

全局下載TypeScript 手動編譯TS文件變成js文件

npm install -g typescript

用全局安裝的typescript來編譯輸出一把剛纔的文件

clipboard.png

尚未編譯,如今已經開始報出問題,可是報出問題能夠繼續編譯嗎?

clipboard.png

即便靜態校驗出現問題,最終仍是編譯成功:

clipboard.png

這裏特別注意, TS裏面的靜態類型,以及枚舉等,編譯成 js後是不存在的

上面並無體現typeScript的特殊價值

TypeScript的核心原則之一是對值所具備的結構進行類型檢查。 它有時被稱作「鴨式辨型法」或「結構性子類型化」。 在TypeScript裏,接口的做用就是爲這些類型命名和爲你的代碼或第三方代碼定義契約。

//接口名爲LabelledValue
interface LabelledValue {
  label: string;
}


//函數傳入的參數 labelledObj遵循 LabelledValue接口 

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

以上代碼通過ts編譯後,全部接口和靜態類型都沒有了 :

function printLabel(labelledObj) {
    console.log(labelledObj.label);
}
var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

若是ts在代碼編寫階段出現了類型的校驗錯誤,那麼會直接提示:

我將接口的string改爲了number類型

clipboard.png

咱們僅僅改變了接口的類型,就馬上檢驗到了錯誤,這樣沒必要等到開發模式下的熱更新調試後再報錯。

固然 你在接口定義時候,能夠在變量後加上?

這樣是一個可選屬性

例如:

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

還有隻讀屬性的接口定義:

interface Point {
    readonly x: number;
    readonly y: number;
}

你能夠經過賦值一個對象字面量來構造一個Point。 賦值後, x和y不再能被改變了。

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

用得比較多的函數類型檢查

先編寫接口

interface SearchFunc {
  (source: string, subString: string): boolean;
}

定義函數

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

對於函數類型的類型檢查來講,函數的參數名不須要與接口裏定義的名字相匹配。 好比,咱們使用下面的代碼重寫上面的例子:

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}

函數的參數會逐個進行檢查,要求對應位置上的參數類型是兼容的。 若是你不想指定類型,TypeScript的類型系統會推斷出參數類型,由於函數直接賦值給了 SearchFunc類型變量。 函數的返回值類型是經過其返回值推斷出來的(此例是 false和true)。 若是讓這個函數返回數字或字符串,類型檢查器會警告咱們函數的返回值類型與 SearchFunc接口中的定義不匹配。

let mySearch: SearchFunc;
mySearch = function(src, sub) {
    let result = src.search(sub);
    return result > -1;
}
鴨式辨形法,說的是:一個動物長得看起來像鴨子,叫起來也像鴨子,那麼它就能夠被認爲是鴨子

定義類的類型:

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

一個接口能夠繼承多個接口,建立出多個接口的合成接口。

interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface Square extends Shape, PenStroke {
    sideLength: number;
}
照本宣科寫了這麼多,其實這些就是 TS的最有用的地方。文檔寫得比較好,建議多去看幾遍,前提是必定要學好 ES6

TS中必定要儘可能避免使用any類型

any類型有太多不可預測的後果

function identity<T>(arg: T): T {
    return arg;
}

咱們給identity添加了類型變量T。 T幫助咱們捕獲用戶傳入的類型(好比:number),以後咱們就可使用這個類型。 以後咱們再次使用了 T當作返回值類型。如今咱們能夠知道參數類型與返回值類型是相同的了。 這容許咱們跟蹤函數裏使用的類型的信息。

其餘的API能夠去刷文檔,下面說重點:

工程化環境:

typescript趕上了webpack

React官方推薦使用typescript

clipboard.png

使用傳統的 react腳手架

在 Create React App 中使用 TypeScript

npx create-react-app my-app --typescript

typescript趕上webpack

切記 全部的 ts的依賴,都必須是 @types開頭的 不然用不了

配置tsconfig.json文件

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ]
}
npm install --save react react-dom @types/react @types/react-dom

webpack.config.js配置文件

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    devtool: "source-map",

    resolve: {
  
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
         
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
};

你們可能對externals字段有所疑惑。 咱們想要避免把全部的React都放到一個文件裏,由於會增長編譯時間而且瀏覽器還可以緩存沒有發生改變的庫文件。

webpack 4.39版配置typeScript

TS最基礎關鍵的核心思想,已經介紹完了

咱們不妨總結一下:

TS最核心的優點 :

靜態類型檢查+校驗,代碼並無運行編譯,就已經知道哪裏有問題了,不管是變量查找仍是類型錯誤

TS給咱們解決了什麼問題

減小了開發溝通成本,打開你的代碼就知道傳入的是什麼參數,返回什麼參數。編譯後代碼量並無增長

TS給咱們帶來了什麼麻煩

多寫了不少接口,類型,一些快速開發的小項目感受用上更麻煩。若是是比較古老的js插件第三方庫,還用不了,要另想其餘辦法去支持。

大型項目,能夠上ts,仍是要上ts,中小型項目,看工期,看你是否打算在時間容許狀況下嘗試使用ts

技術自己沒有好壞,長遠看,弱類型語言並非那麼的友好。谷歌的Go語言,寫法就跟TypeScript很像,若是想要擁有更廣闊的技術視野,建議前端是能夠從TS學起,他們的思想大都差很少。

最後,歡迎你們加入咱們的segmentFault前端交流羣,個人我的微信是:CALASFxiaotan,加我會拉你進羣哦~

羣裏大把小姐姐等大家~

clipboard.png

以爲寫得好,記得點個贊哦,永不脫髮
相關文章
相關標籤/搜索