TypeScript 簡介

建了個羣有興趣的朋友能夠加一下 QQ 羣:Angular 修仙之路(1)羣 - 153742079 (已滿),請加 Angular 修仙之路(2)羣 - 648681235。html

TypeScript 是什麼

TypeScript 是一種由微軟開發的自由和開源的編程語言。它是 JavaScript 的一個超集,並且本質上向這個語言添加了可選的靜態類型和基於類的面向對象編程。
TypeScript 擴展了 JavaScript 的句法,因此任何現有的 JavaScript 程序能夠不加改變的在 TypeScript 下工做。TypeScript 是爲大型應用之開發而設計,而編譯時它產生 JavaScript 以確保兼容性。node

typescript-and-es-feature

安裝 TypeScript

$ npm install -g typescript

編譯 TypeScript 文件

$ tsc app.ts # app.ts => app.js

TypeScript 數據類型

Boolean 類型

let isDone: boolean = false; // tsc => var isDone = false;

Number 類型

let count: number = 10;  // tsc => var count = 10

String 類型

let name: string = 'Semliker'; // tsc => var name = 'Semlinker'

Array 類型

let list: number[] = [1,2,3]; // tsc => var list = [1,2,3];   

let list: Array<number> = [1,2,3]; 
// tsc => var list = [1,2,3];

Enum 類型

enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST
}; 

let dir: Direction = Direction.NORTH;

Any (動態類型)

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; 

=> tsc =>  

var notSure = 4;
notSure = "maybe a string instead";
notSure = false;

Void

某種程度上來講,void 類型像是與 any 類型相反,它表示沒有任何類型。當一個函數沒有返回值時,你一般會見到其返回值類型是 void:react

// 聲明函數返回值爲void
function warnUser(): void { 
    console.log("This is my warning message");
}

=> tsc =>  

function warnUser() {
    console.log("This is my warning message");
}

須要注意的是,聲明一個 void 類型的變量沒有什麼做用,由於它的值只能爲 undefinednulltypescript

let unusable: void = undefined;

Tuple

元組類型容許表示一個已知元素數量和類型的數組,各元素的類型沒必要相同。好比,你能夠定義一對值分別爲 stringnumber 類型的元組。shell

let x: [string, number];

x = ['semlinker', 10]; // 正常賦值

x = [10, 'semlinker']; // 類型不匹配

當訪問一個已知索引的元素,會獲得正確的類型:express

console.log(x[0].substr(1)); // OK

// Error, 'number' does not have 'substr' method
console.log(x[1].substr(1));

當訪問一個越界的元素,會使用聯合類型替代:npm

x[3] = 'world'; // OK, 字符串能夠賦值給(string | number) 類型

console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toString 方法

x[6] = true; // Error, 布爾不是(string | number) 類型

TypeScript Assertion

有時候你會遇到這樣的狀況,你會比 TypeScript 更瞭解某個值的詳細信息。一般這會發生在你清楚地知道一個實體具備比它現有類型更確切的類型。編程

經過類型斷言這種方式能夠告訴編譯器,"相信我,我知道本身在幹什麼"。類型斷言比如其餘語言裏的類型轉換,可是不進行特殊的數據檢查和解構。它沒有運行時的影響,只是在編譯階段起做用。json

類型斷言有兩種形式:數組

  • "尖括號"語法

let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
  • as 語法

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

TypeScript Union Types and Type Aliases

Union Types

let greet = (message: string | string[]) => {
  if(message instanceof Array) {
    let messages = "";
    message.forEach((msg) => {
      messages += ` ${msg}`;
    });
    console.log("Received messages ", messages);
  } else {
    console.log("Received message = ", message);
  }
};

greet('semlinker');
greet(['Hello', 'Angular']);

Type Aliases

type Message = string | string[];
let greet = (message: Message) => { 
  // ... 
};

TypeScript Function

TypeScript 函數與 JavaScript 函數的區別

TypeScript JavaScript
Types No types
Arrow function Arrow function (ES2015)
Function types No Function types
Required and Optional parameters All parameters are optional
Default parameters Default parameters
Rest parameters Rest parameters
Overloaded function No overloaded functions

箭頭函數

  • 常見語法

myBooks.forEach(() => console.log('Done reading'));

myBooks.forEach(title => console.log(title));

myBooks.forEach((title, idx, arr) => 
  console.log(idx + '-' + title);
);

myBooks.forEach((title, idx, arr) => {
  console.log(idx + '-' + title);
});
  • 使用示例

// 未使用箭頭函數
function Book() {
  let self = this;
  self.publishDate = 2016;
  setInterval(function() {
    console.log(self.publishDate);
  }, 1000);
}

// 使用箭頭函數
function Book() {
  this.publishDate = 2016;
  setInterval(() => {
    console.log(this.publishDate);
  }, 1000);
}

參數類型和返回類型

function createUserId(name: string, id: number): string {
  return name + id;
}

函數類型

let IdGenerator: (chars: string, nums: number) => string;

function createUserId(name: string, id: number): string {
  return name + id;
}

IdGenerator = createUserId;

可選參數及默認參數

// 可選參數
function createUserId(name: string, age?: number, 
  id: number): string {
    return name + id;
}

// 默認參數
function createUserId(name: string = 'Semlinker', age?: number, 
  id: number): string {
    return name + id;
}

剩餘參數

function push(array, ...items) {
  items.forEach(function(item) {
    array.push(item);
  });
}

let a = [];
push(a, 1, 2, 3);

TypeScript Array

數組解構

let x: number, let y: number ,let z: number;
let five_array = [0,1,2,3,4];
[x,y,z] = five_array;

數組展開運算符

let two_array = [0,1];
let five_array = [...two_array,2,3,4];

數組循環

let colors: string[] = ["red", "green", "blue"];
for(let i in colors) {
  console.log(i);
}

TypeScript Object

對象解構

let person = {
  name: 'Semlinker',
  gender: 'male'
};

let {name, gender} = person;

對象展開運算符

let person = {
  name: 'Semlinker',
  gender: 'male',
  address: 'Xiamen'
};

// 組裝對象
let personWithAge = {...person, age: 31};

// 獲取除了某些項外的其它項
let {name, ...rest} = person;

TypeScript Interface

在面嚮對象語言中,接口(Interfaces)是一個很重要的概念,它是對行爲的抽象,而具體如何行動須要由類(classes)去實現(implements)。

TypeScript 中的接口是一個很是靈活的概念,除了可用於對類的一部分行爲進行抽象之外,也經常使用於對「對象的形狀(Shape)」進行描述。

對象的形狀

interface Person {
  name: string;
  age: number;
}

let semlinker: Person = {
  name: 'Semlinker',
  age: 31
};

可選 | 只讀屬性

interface Person {
  readonly name: string;
  age?: number;
}

TypeScript Class

在面嚮對象語言中,類是一種面向對象計算機編程語言的構造,是建立對象的藍圖,描述了所建立的對象共同的屬性和方法。

在 TypeScript 中,咱們能夠經過 Class 關鍵字來定義一個類:

class Greeter {
   static cname: string = 'Greeter'; // 靜態屬性
   greeting: string; // 成員屬行

   constructor(message: string) { // 構造函數 - 執行初始化操做
     this.greeting = message;
   }

    static getClassName() { // 靜態方法
      return 'Class name is Greeter';
    }
    
    greet() { // 成員方法
      return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

TypeScript Accessors

在 TypeScript 中,咱們能夠經過 gettersetter 方法來實現數據的封裝和有效性校驗,防止出現異常數據。

let passcode = "hello angular 5";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

    set fullName(newName: string) {
        if (passcode && passcode == "hello angular 5") {
            this._fullName = newName;
        }
        else {
            console.log("Error: Unauthorized update of employee!");
        }
    }
}

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    console.log(employee.fullName);
}

TypeScript Inheritance

繼承 (Inheritance) 是一種聯結類與類的層次模型。指的是一個類 (稱爲子類、子接口) 繼承另外的一個類 (稱爲父類、父接口) 的功能,並能夠增長它本身的新功能的能力,繼承是類與類或者接口與接口之間最多見的關係;繼承是一種 is-a 關係。

class-inheritance

在 TypeScripe 中,咱們能夠經過 extends 關鍵字來實現繼承:

class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

let sam = new Snake("Sammy the Python");
sam.move();

TypeScript Generics

泛型(Generics)是容許同一個函數接受不一樣類型參數的一種模板。相比於使用 any 類型,使用泛型來建立可複用的組件要更好,由於泛型會保留參數類型。

泛型接口

interface GenericIdentityFn<T> {
    (arg: T): T;
}

泛型類

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; };

使用示例

interface Hero { // Hero 接口
    id: number;
    name: string;
}

getHeroes(): Observable<Hero[]> {
  return Observable.of([
     { id: 1, name: 'Windstorm' },
     { id: 13, name: 'Bombasto' },
     { id: 15, name: 'Magneta' },
     { id: 20, name: 'Tornado' }
  ]);
}

上面 getHeroes(): Observable<Hero[]> 表示調用 getHeroes() 方法後返回的是一個 Observable 對象,<Hero[]> 用於表示該 Observable 對象的觀察者,將會收到的數據類型。示例中表示將會返回 <Hero[]> 英雄列表。

tsconfig.json 簡介

tsconfig.json 的做用

  • 用於標識 TypeScript 項目的根路徑

  • 用於配置 TypeScript 編譯器

  • 用於指定編譯的文件

tsconfig.json 重要字段

  • files - 設置要編譯的文件的名稱

  • include - 設置須要進行編譯的文件,支持路徑模式匹配

  • exclude - 設置無需進行編譯的文件,支持路徑模式匹配

  • compilerOptions - 設置與編譯流程相關的選項

tsconfig.json - compilerOptions

字段 說明
target Desired ECMAScript version (es3,es5,es2015,es2016,es2017, or esNext)
rootDir Root directory of input files
listFiles Print file names processed by the compiler
outDir Directory to contain compiled results
outFile File to contain concatenated results
watch Watch input files
removeComments Remove comments from generated output
noLib Don't include the main library, lib.d.ts, in the compilation process
alwaysStrict Specifies whether strict mode should be enabled
noEmitOnError Don't generate output if any errors were encounted
noImplicitThis Raise an error on this expressions with implied any type
noUnuseLocals Report errors on unused parameters
noImplicitAny Print a warning for every variable that isn't explicitly declared
suppressImplicit Any IndexErrors Suppress Implicit AnyIndexError
skipLibCheck Suppress type checking of declarations files
experimental Decorators Enable support for ES7 decorators
declaration Generate declaration file(*.d.ts) for the TypeScript code
declarationDir Place declaration files in the given directory
module The formate of the generated module (commonjs, amd, system, umd, or es2015)
noEmitHelpers Do not insert custom helper functions in generated output
emitDecoratorMetadata Insert metadata for TypeScript decorations
isolatedModule Always insert imports for unresolved files
jsx Generate JSC code (preserve or react)
moduleResolution Strategy for resolving module (node or classic)

tsconfig.json 示例

{
  "files": ["src/app/app.ts"],
  "compilerOptions": {
    "target": "es5",
    "removeComments": true,
    "alwaysStrict": true,
    "noEmitOnError": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}
  • alwaysStrict - ES 5 代碼將在嚴格模式下執行

  • noEmitOnError - 表示當發生錯誤的時候,編譯器不要生成 JavaScript 代碼

  • noUnusedLocals 和 noUnusedParameters - 表示編譯器將檢測沒有使用的變量或參數

相關文章
相關標籤/搜索