TypeScript 簡介

TypeScript 是什么

TypeScript 是一種由微軟開發(fā)的自由和開源的編程語言。它是 JavaScript 的一個超集,而且本質(zhì)上向這個語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊獭?br> TypeScript 擴展了 JavaScript 的句法,所以任何現(xiàn)有的 JavaScript 程序可以不加改變的在 TypeScript 下工作。TypeScript 是為大型應(yīng)用之開發(fā)而設(shè)計,而編譯時它產(chǎn)生 JavaScript 以確保兼容性。

ts-and-es-feature.png

安裝 TypeScript

$ npm install -g typescript  

編譯 TypeScript 文件

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

TypeScript 數(shù)據(jù)類型

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 (動態(tài)類型)

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 類型相反,它表示沒有任何類型。當(dāng)一個函數(shù)沒有返回值時,你通常會見到其返回值類型是 void:

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

=> tsc =>  

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

需要注意的是,聲明一個 void 類型的變量沒有什么作用,因為它的值只能為 undefinednull

let unusable: void = undefined;

Tuple

元組類型允許表示一個已知元素數(shù)量和類型的數(shù)組,各元素的類型不必相同。比如,你可以定義一對值分別為 stringnumber 類型的元組。

let x: [string, number];

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

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

當(dāng)訪問一個已知索引的元素,會得到正確的類型:

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

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

當(dāng)訪問一個越界的元素,會使用聯(lián)合類型替代:

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

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

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

TypeScript Assertion

有時候你會遇到這樣的情況,你會比 TypeScript 更了解某個值的詳細信息。通常這會發(fā)生在你清楚地知道一個實體具有比它現(xiàn)有類型更確切的類型。

通過類型斷言這種方式可以告訴編譯器,"相信我,我知道自己在干什么"。類型斷言好比其他語言里的類型轉(zhuǎn)換,但是不進行特殊的數(shù)據(jù)檢查和解構(gòu)。它沒有運行時的影響,只是在編譯階段起作用。

類型斷言有兩種形式:

  • "尖括號"語法
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 函數(shù)與 JavaScript 函數(shù)的區(qū)別

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

箭頭函數(shù)

  • 常見語法
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);
});
  • 使用示例
// 未使用箭頭函數(shù)
function Book() {
  let self = this;
  self.publishDate = 2016;
  setInterval(function() {
    console.log(self.publishDate);
  }, 1000);
}

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

參數(shù)類型和返回類型

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

函數(shù)類型

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

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

IdGenerator = createUserId;

可選參數(shù)及默認參數(shù)

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

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

剩余參數(shù)

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

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

TypeScript Array

數(shù)組解構(gòu)

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

數(shù)組展開運算符

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

數(shù)組循環(huán)

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

TypeScript Object

對象解構(gòu)

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

在面向?qū)ο笳Z言中,接口(Interfaces)是一個很重要的概念,它是對行為的抽象,而具體如何行動需要由類(classes)去實現(xiàn)(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

在面向?qū)ο笳Z言中,類是一種面向?qū)ο笥嬎銠C編程語言的構(gòu)造,是創(chuàng)建對象的藍圖,描述了所創(chuàng)建的對象共同的屬性和方法。

在 TypeScript 中,我們可以通過 Class 關(guān)鍵字來定義一個類:

class Greeter {
   static cname: string = 'Greeter'; // 靜態(tài)屬性
   greeting: string; // 成員屬行

   constructor(message: string) { // 構(gòu)造函數(shù) - 執(zhí)行初始化操作
     this.greeting = message;
   }

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

let greeter = new Greeter("world");

TypeScript Accessors

在 TypeScript 中,我們可以通過 gettersetter 方法來實現(xiàn)數(shù)據(jù)的封裝和有效性校驗,防止出現(xiàn)異常數(shù)據(jù)。

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) 是一種聯(lián)結(jié)類與類的層次模型。指的是一個類 (稱為子類、子接口) 繼承另外的一個類 (稱為父類、父接口) 的功能,并可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關(guān)系;繼承是一種 is-a 關(guān)系。

class-inheritance

在 TypeScripe 中,我們可以通過 extends 關(guān)鍵字來實現(xiàn)繼承:

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)是允許同一個函數(shù)接受不同類型參數(shù)的一種模板。相比于使用 any 類型,使用泛型來創(chuàng)建可復(fù)用的組件要更好,因為泛型會保留參數(shù)類型。

泛型接口

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[]> 表示調(diào)用 getHeroes() 方法后返回的是一個 Observable 對象,<Hero[]> 用于表示該 Observable 對象的觀察者,將會收到的數(shù)據(jù)類型。示例中表示將會返回 <Hero[]> 英雄列表。

tsconfig.json 簡介

tsconfig.json 的作用

  • 用于標(biāo)識 TypeScript 項目的根路徑
  • 用于配置 TypeScript 編譯器
  • 用于指定編譯的文件

tsconfig.json 重要字段

  • files - 設(shè)置要編譯的文件的名稱
  • include - 設(shè)置需要進行編譯的文件,支持路徑模式匹配
  • exclude - 設(shè)置無需進行編譯的文件,支持路徑模式匹配
  • compilerOptions - 設(shè)置與編譯流程相關(guān)的選項

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 代碼將在嚴(yán)格模式下執(zhí)行
  • noEmitOnError - 表示當(dāng)發(fā)生錯誤的時候,編譯器不要生成 JavaScript 代碼
  • noUnusedLocals 和 noUnusedParameters - 表示編譯器將檢測沒有使用的變量或參數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 TypeScript本質(zhì)上是向JavaScript語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊?,同時也支持...
    oWSQo閱讀 8,683評論 1 45
  • 前言 人生苦多,快來 Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,703評論 9 118
  • { "Unterminated string literal.": "未終止的字符串文本。", "Identifi...
    一粒沙隨風(fēng)飄搖閱讀 11,344評論 0 3
  • 但凡上過學(xué)的人就知道,在學(xué)校里面總有那么一群人,他們不學(xué)無術(shù),或者很想好好學(xué)習(xí),但是就是學(xué)不會。這是因為智商的問題...
    葉浟閱讀 659評論 3 8
  • vita9閱讀 589評論 0 0

友情鏈接更多精彩內(nèi)容