鍍金池/ 教程/ HTML/ TypeScript 1.4
初始化項(xiàng)目結(jié)構(gòu)
聯(lián)合類型
介紹
介紹
介紹
編譯選項(xiàng)
TypeScript 1.6
介紹
介紹
發(fā)展路線圖
介紹
在MSBuild里使用編譯選項(xiàng)
可迭代性
TypeScript 1.3
介紹
介紹
TypeScript 1.1
變量聲明
即將到來的Angular 2框架是使用TypeScript開發(fā)的。 因此Angular和TypeScript一起使用非常簡單方便
tsconfig.json
介紹
介紹
介紹
在MSBuild里使用編譯選項(xiàng)
使用TypeScript的每日構(gòu)建版本
新建工程
枚舉
三斜線指令
結(jié)合ASP.NET v5使用TypeScript
TypeScript里的this
介紹
TypeScript 1.4
編碼規(guī)范
介紹
模塊解析
ASP.NET 4
架構(gòu)概述
介紹
介紹
ASP.NET Core
TypeScript 1.8
介紹
介紹
創(chuàng)建簡單工程
TypeScript 1.7
TypeScript 1.5
NPM包的類型
支持TypeScript的編輯器

TypeScript 1.4

聯(lián)合類型

概述

聯(lián)合類型有助于表示一個(gè)值的類型可以是多種類型之一的情況。比如,有一個(gè)API接命令行傳入string類型,string[]類型或者是一個(gè)返回string的函數(shù)。你就可以這樣寫:

interface RunOptions {
   program: string;
   commandline: string[]|string|(() => string);
}

給聯(lián)合類型賦值也很直觀 -- 只要這個(gè)值能滿足聯(lián)合類型中任意一個(gè)類型那么就可以賦值給這個(gè)聯(lián)合類型:

var opts: RunOptions = /* ... */;
opts.commandline = '-hello world'; // OK
opts.commandline = ['-hello', 'world']; // OK
opts.commandline = [42]; // Error, 數(shù)字不是字符串或字符串?dāng)?shù)組

當(dāng)讀取聯(lián)合類型時(shí),你可以訪問類型共有的屬性:

if(opts.length === 0) { // OK, string和string[]都有'length'屬性
  console.log("it's empty");
}

使用類型保護(hù),你可以輕松地使用聯(lián)合類型:

function formatCommandline(c: string|string[]) {
    if(typeof c === 'string') {
        return c.trim();
    } else {
        return c.join(' ');
    }
}

嚴(yán)格的泛型

隨著聯(lián)合類型可以表示有很多類型的場景,我們決定去改進(jìn)泛型調(diào)用的規(guī)范性。之前,這段代碼編譯不會(huì)報(bào)錯(cuò)(出乎意料):

function equal<T>(lhs: T, rhs: T): boolean {
  return lhs === rhs;
}

// 之前沒有錯(cuò)誤
// 現(xiàn)在會(huì)報(bào)錯(cuò):在string和number之前沒有最佳的基本類型
var e = equal(42, 'hello');

通過聯(lián)合類型,你可以指定你想要的行為,在函數(shù)定義時(shí)或在調(diào)用的時(shí)候:

// 'choose' function where types must match
function choose1<T>(a: T, b: T): T { return Math.random() > 0.5 ? a : b }
var a = choose1('hello', 42); // Error
var b = choose1<string|number>('hello', 42); // OK

// 'choose' function where types need not match
function choose2<T, U>(a: T, b: U): T|U { return Math.random() > 0.5 ? a : b }
var c = choose2('bar', 'foo'); // OK, c: string
var d = choose2('hello', 42); // OK, d: string|number

更好的類型推斷

當(dāng)一個(gè)集合里有多種類型的值時(shí),聯(lián)合類型會(huì)為數(shù)組或其它地方提供更好的類型推斷:

var x = [1, 'hello']; // x: Array<string|number>
x[0] = 'world'; // OK
x[0] = false; // Error, boolean is not string or number

let 聲明

在JavaScript里,var聲明會(huì)被“提升”到所在作用域的頂端。這可能會(huì)引發(fā)一些讓人不解的bugs:

console.log(x); // meant to write 'y' here
/* later in the same block */
var x = 'hello';

TypeScript已經(jīng)支持新的ES6的關(guān)鍵字let,聲明一個(gè)塊級(jí)作用域的變量。一個(gè)let變量只能在聲明之后的位置被引用,并且作用域?yàn)槁暶魉膲K里:

if(foo) {
    console.log(x); // Error, cannot refer to x before its declaration
    let x = 'hello';
} else {
    console.log(x); // Error, x is not declared in this block
}

let只在設(shè)置目標(biāo)為ECMAScript 6 (--target ES6)時(shí)生效。

const 聲明

另一個(gè)TypeScript支持的ES6里新出現(xiàn)的聲明類型是const。不能給一個(gè)const類型變量賦值,只能在聲明的時(shí)候初始化。這對(duì)于那些在初始化之后就不想去改變它的值的情況下是很有幫助的:

const halfPi = Math.PI / 2;
halfPi = 2; // Error, can't assign to a `const`

const只在設(shè)置目標(biāo)為ECMAScript 6 (--target ES6)時(shí)生效。

模版字符串

TypeScript現(xiàn)已支持ES6模塊字符串。通過它可以方便地在字符串中嵌入任何表達(dá)式:

var name = "TypeScript";
var greeting  = `Hello, ${name}! Your name has ${name.length} characters`;

當(dāng)編譯目標(biāo)為ES6之前的版本時(shí),這個(gè)字符串被分解為:

var name = "TypeScript!";
var greeting = "Hello, " + name + "! Your name has " + name.length + " characters";

類型守護(hù)

JavaScript常用模式之一是在運(yùn)行時(shí)使用typeofinstanceof檢查表達(dá)式的類型。 在if語句里使用它們的時(shí)候,TypeScript可以識(shí)別出這些條件并且隨之改變類型推斷的結(jié)果。

使用typeof來檢查一個(gè)變量:

var x: any = /* ... */;
if(typeof x === 'string') {
    console.log(x.subtr(1)); // Error, 'subtr' does not exist on 'string'
}
// x is still any here
x.unknown(); // OK

結(jié)合聯(lián)合類型使用typeofelse

var x: string|HTMLElement = /* ... */;
if(typeof x === 'string') {
    // x is string here, as shown above
} else {
    // x is HTMLElement here
    console.log(x.innerHTML);
}

結(jié)合類和聯(lián)合類型使用instanceof

class Dog { woof() { } }
class Cat { meow() { } }
var pet: Dog|Cat = /* ... */;
if(pet instanceof Dog) {
    pet.woof(); // OK
} else {
    pet.woof(); // Error
}

類型別名

你現(xiàn)在可以使用type關(guān)鍵字來為類型定義一個(gè)“別名”:

type PrimitiveArray = Array<string|number|boolean>;
type MyNumber = number;
type NgScope = ng.IScope;
type Callback = () => void;

類型別名與其原始的類型完全一致;它們只是簡單的替代名。

const enum(完全嵌入的枚舉)

枚舉很有幫助,但是有些程序?qū)嶋H上并不需要它生成的代碼并且想要將枚舉變量所代碼的數(shù)字值直接替換到對(duì)應(yīng)位置上。新的const enum聲明與正常的enum在類型安全方面具有同樣的作用,只是在編譯時(shí)會(huì)清除掉。

const enum Suit { Clubs, Diamonds, Hearts, Spades }
var d = Suit.Diamonds;

Compiles to exactly:

var d = 1;

TypeScript也會(huì)在可能的情況下計(jì)算枚舉值:

enum MyFlags {
  None = 0,
  Neat = 1,
  Cool = 2,
  Awesome = 4,
  Best = Neat | Cool | Awesome
}
var b = MyFlags.Best; // emits var b = 7;

-noEmitOnError 命令行選項(xiàng)

TypeScript編譯器的默認(rèn)行為是當(dāng)存在類型錯(cuò)誤(比如,將string類型賦值給number類型)時(shí)仍會(huì)生成.js文件。這在構(gòu)建服務(wù)器上或是其它場景里可能會(huì)是不想看到的情況,因?yàn)橄M玫降氖且淮巍凹儍簟钡臉?gòu)建。新的noEmitOnError標(biāo)記可以阻止在編譯時(shí)遇到錯(cuò)誤的情況下繼續(xù)生成.js代碼。

它現(xiàn)在是MSBuild工程的默認(rèn)行為;這允許MSBuild持續(xù)構(gòu)建以我們想要的行為進(jìn)行,輸出永遠(yuǎn)是來自純凈的構(gòu)建。

AMD 模塊名

默認(rèn)情況下AMD模塊以匿名形式生成。這在使用其它工具(比如,r.js)處理生成的模塊的時(shí)可能會(huì)帶來麻煩。

新的amd-module name標(biāo)簽允許給編譯器傳入一個(gè)可選的模塊名:

//// [amdModule.ts]
///<amd-module name='NamedModule'/>
export class C {
}

結(jié)果會(huì)把NamedModule賦值成模塊名,做為調(diào)用AMDdefine的一部分:

//// [amdModule.js]
define("NamedModule", ["require", "exports"], function (require, exports) {
    var C = (function () {
        function C() {
        }
        return C;
    })();
    exports.C = C;
});