TypeScript基礎總結

導語: TypeScript(如下簡稱TS) 是由微軟開發的編程語言,是JavaScript的超集,於2013年10月發佈第一個正式版0.9。最早代碼託管在Codeplex,2014年7月移到了Github。它的代碼風格和C#很像,這是由於TS是由C#首席架構師設計並主導開發的。

開發環境

編輯器首選MS自家開發的VS Code (推薦)。固然,Webstorm在2016年2月推出的版本內置了TS編譯器,atom 須要安裝 atom-typescript包,sublime須要安裝Typescript-sublime-plugin。javascript

TS程序以.ts擴展名結尾。運行TS程序很簡單,只須要安裝編譯器TS compile便可,須要經過npm 的方式安裝它。java

npm install typescript -g

安裝完後,在全局會有tsc命令,須要經過它編譯TS程序webpack

tsc hello.ts

類型系統

談到TS,你們印象最深入的仍是TS的靜態強類型了。雖然JS異常靈活,可是在大型複雜的web工程裏面並不合適。除了TS,其它公司好比FB推出了Flow,Google推出了Clojure,這些都是爲了給JS增長類型。web

類型註解

概念:註解是一種輕量級的爲函數或變量添加約束的方式。
語法:變量或者函數後接 :TypeAnnotationtypescript

好比:express

let a: number = 123;

function add(a: number, b: number): number {
    return a + b;
}

原始類型

TS裏的原始類型包括string, number和boolean,這些也是JS的原始類型。在TS裏,你能夠顯示聲明變量爲某一種類型。npm

let num: number;
let str: string;
let bool: boolean;

num = 123;
num = 123.456;
num = '123';     // 錯誤

str = '123';
str = 123;       // 錯誤

bool = true;
bool = false;
bool = 'false';  // 錯誤

數組

TS裏手動指明一個數組類型很簡單,只須要在普通類型註解後面加上[]符號。好比聲明一個布爾數組爲 :boolean[]編程

let boolArray: boolean[];

boolArray = [true, false];
console.log(boolArray[0]);     // true
console.log(boolArray.length); // 2
boolArray[1] = true;
boolArray = [false, false];

boolArray[0] = 'false';        // 錯誤
boolArray = 'false';           // 錯誤
boolArray = [true, 'false'];   // 錯誤

枚舉

枚舉在TS裏面是原生支持的,使用枚舉咱們能夠定義一些帶名字的常量,它的好處是可讓語意更清晰。定義一個枚舉值,須要使用 enumjson

TS 僅支持基於數字的和字符串的枚舉。若是是數字枚舉,枚舉值默認是從0開始,依次自增的。你也能夠手動的設置第一個枚舉值,好比爲1。數組

enum Color {
    RED = 1,
    GREEN,
    YELLOW
}
console.log(Color.GREEN);   // 2

enum Direction {
    UP = 'UP',
    DOWN = 'DOWN',
    LEFT = 'LEFT',
    RIGHT = 'RIGHT'
}
console.log(Direction.UP);   // 'UP'

雖然TS支持異構枚舉(即數字和字符串混搭的枚舉),可是並不建議使用這種方式。

特殊類型

  • any: 任何元素均可以賦值給它,它也能夠賦值給任何元素。至關於關掉類型檢查,適用 js 代碼遷移到 ts。
  • null: 能夠賦值給任何元素
  • undefined: 能夠賦值給任何元素
  • void: 表示函數沒有返回類型

接口

和其它語言(好比C++, java)不一樣的是,TS 裏接口能夠描述變量、函數類型和類類型,其它語言只能描述類類型。另外,TS中的接口描述變量時可使用?定義某個變量爲可選變量。好比對某個對象進行約束時,若是對象的某個屬性設置成了可選,則傳入的對象能夠不包含這個屬性。

interface LabelledValue {
    size?: Number,
    label: String
}

function printLabel(labelObject: LabelledValue) {
    return labelObject.label;
}

// 因爲size設置成了可選變量,則傳入的對象能夠不包含size屬性
console.log(printLabel({
    label: 'size 1 object'
}));

接口-描述函數類型

接口出了能夠用來約束JS對象以外,也能夠用來約束函數類型。好比:

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

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

說明:對於函數類型的類型檢查來講,函數的參數名不須要與接口裏定義的名字相匹配。

接口 - 描述類類型

與C#或Java裏接口的基本做用同樣,TypeScript也可以用它來明確的強制一個類去符合某種契約。不一樣的是,C#或Java裏面的接口描述類類型時,只能定義函數,TS裏則還能夠定義屬性。若是某個類繼承了這個接口,那麼這個類必須包含接口裏定義的屬性和方法。

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

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

泛型

設計的出發點:可重用性。組件不只可以支持當前的數據類型,同時也能支持將來的數據類型。

好比咱們須要一個函數,同時支持入參是一個數字或字符串,返回值的類型和參數類型相同:

function identity(arg: number): number {
   return arg;
}

function identity(arg: string): string {
   return arg;
}

這個時候就須要引入泛型去解決這個問題了。在TS裏,泛型的類型變量定義爲T,須要使用<>包裹起來,這個時候函數會捕獲入參的類型,而後在後面就可使用這個類型了。以下:。

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

let output1 = identity<string>("myString");   // myString
let output2 = identity("myString");           // myString

因爲TS的類型推斷,調用時不須要顯示的指明類型,推薦使用上面代碼中的第二種方式。

高級特性

  • 訪問修飾符:public能夠被自由訪問,private在類外沒法訪問。protected能夠被派生類(子類)訪問。
  • static關鍵字:能夠用來修飾類的屬性和方法,靜態屬性和靜態方法存在類上而不是實例上,能夠經過 」類名.」 的方式來訪問。
  • readonly關鍵字:屬性初始化以後不可修改。

    • 備註:readonly和const區別:const用來修飾變量,readonly用來修飾屬性。

抽象類

定義:經過 abstract 來修飾的類稱爲抽象類。

特色:

  • 抽象類不能直接實例化,即不能經過 new X()的方式調用。
  • 抽象類必須包含一些抽象方法,抽象方法也用 abstract修飾
  • 抽象類中的抽象方法不包含具體實現,可是必須在派生類中實現。

值得一提的是:抽象類和接口在描述類類型時,雖然比較相似。可是抽象類只能繼承一個抽象類或者一個接口,而接口能夠多重繼承。

裝飾器

Decorator是一個函數,用來修飾類、屬性、方法和參數。使用 @expression 語。

Decorator 的改變是在編譯期改變,而不是運行期。裝飾器包括多個規範,TC39在stage-0 和 stage-2分別定了修飾屬性、方法的規範和修飾類的規範。

類裝飾器

@func 修飾 類A 等價於 A = func(A),至關於把舊class轉換成了新的class。能夠理解爲一個加工函數,它接受一個類,加工後返回另外一個類。

@testable
class MyTestableClass {
  // ...
}
 
function testable(target) {
  target.isTestable = true;
  return target;
}

function getMetaData(target) {
    return target.isTestable;
}

console.log(getMetaData(MyTestableClass))  // true

方法裝飾器

裝飾器除了修飾類以外,也能夠用來修飾方法:

class A {
    @func()
    static method() {

    }
}

function func() {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        console.log('func 被調用了');
    };
}

A.method();

@func 修飾 類A 上的 方法 method 是藉助 Object 基類上的 defineProperty來實現的。原理以下:

const oldDescriptor = Object.getOwnPropertyDescriptor(A.property, 'method');
const newDescriptor = func(A.property, 'method', 'oldDescriptor');
Object.defineProperty(A.property, 'method', newDescriptor);

工程應用

tsconfig.json

tsconfig.json是TS項目的配置文件,能夠描述整個工程的編譯參數。

初始化一個 tsconfig.json 命令:

$ tsc --init

tsconfig.json裏面的經常使用字段解釋以下:

  • target: 編譯的目標平臺,es3, es5, es2015, es2016, es2017
  • module: 代碼模塊加載器 (commonjs, and 或者es2015)
  • sourceMap: 是否生成映射文件(true 或 false)
  • outDir: 指定輸出目錄
  • exclude: 不包含的編譯目錄

與webpack結合

要想在webpack裏面使用TS,只需兩步。第一,安裝ts-loader;第二,設置webpack配置中的resolve.extension 包含 .ts 和 .tsx。

下面是一個最簡單的配置:

// webpack.config.js

module.exports = {
    entry: "./src/index.ts",
    output: {
        filename: "./dist/bundle.js",
    },
    resolve: {
      extensions: ['.ts', '.js', '.json']
    },
    devtool: "source-map",
    module: {
        rules: [{
            test: /\.tsx?$/,
            loader: 'ts-loader'
        }]
    },
};

TS的優點

整體而言,TS相比ES6 + babel,包含如下優點:

  • 類型檢查
  • TS對ECMAScript新特性支持的更全面,開箱即用。babel中支持新的ES特性須要安裝各類插件,比較繁瑣。
  • TS 寫出來的代碼可讀性更好
  • VS裏的jsdoc,調用棧更加清晰。
相關文章
相關標籤/搜索