在 ES6 目標中支援 async/await(Node v4+)
對於原生支援 ES6 生成器(generator)的引擎(例如 Node v4 及以上版本),TypeScript 現在支援非同步函式。非同步函式以 async 關鍵字作為字首;await 會暫停執行,直到非同步函式返回的 Promise 被兌現(fulfilled),並從返回的 Promise 中解包出該值。
示例
在下面的示例中,每個輸入元素將以 400ms 的間隔逐個打印出來。
ts"use strict";// printDelayed is a 'Promise<void>'async function printDelayed(elements: string[]) {for (const element of elements) {await delay(400);console.log(element);}}async function delay(milliseconds: number) {return new Promise<void>((resolve) => {setTimeout(resolve, milliseconds);});}printDelayed(["Hello", "beautiful", "asynchronous", "world"]).then(() => {console.log();console.log("Printed every element!");});
更多資訊請參閱 async 函式參考。
支援 --target ES6 與 --module 聯用
TypeScript 1.7 在 module 選項的可選列表中增加了 ES6,並允許在目標為 ES6 時指定模組輸出。這為針對特定執行時精確選擇所需的功能提供了更大的靈活性。
示例
{"": {"": "amd","": "es6"}}
this 型別
從方法中返回當前物件(即 this)以建立流式 API(fluent-style APIs)是一種常見的模式。例如,考慮以下 BasicCalculator 模組:
tsexport default class BasicCalculator {public constructor(protected value: number = 0) {}public currentValue(): number {return this.value;}public add(operand: number) {this.value += operand;return this;}public subtract(operand: number) {this.value -= operand;return this;}public multiply(operand: number) {this.value *= operand;return this;}public divide(operand: number) {this.value /= operand;return this;}}
使用者可以將 2 * 5 + 1 表示為:
tsimport calc from "./BasicCalculator";let v = new calc(2).multiply(5).add(1).currentValue();
這種方式通常能帶來非常優雅的程式碼編寫體驗;然而,對於想要擴充套件 BasicCalculator 的類來說,存在一個問題。想象一下,如果使用者想要開始編寫一個 ScientificCalculator:
tsimport BasicCalculator from "./BasicCalculator";export default class ScientificCalculator extends BasicCalculator {public constructor(value = 0) {super(value);}public square() {this.value = this.value ** 2;return this;}public sin() {this.value = Math.sin(this.value);return this;}}
因為 TypeScript 過去會將 BasicCalculator 中返回 this 的每個方法的返回型別推斷為 BasicCalculator,所以在使用 BasicCalculator 方法時,型別系統會“忘記”它原本是 ScientificCalculator。
例如:
tsimport calc from "./ScientificCalculator";let v = new calc(0.5).square().divide(2).sin() // Error: 'BasicCalculator' has no 'sin' method..currentValue();
現在情況不再如此——TypeScript 現在在類的例項方法內部,會將 this 推斷為一種特殊的型別,稱為 this 型別。this 型別寫出來就是這樣,它基本上意味著“方法呼叫中點號左側的型別”。
this 型別在結合交叉型別(intersection types)來描述使用 mixin 風格模式描述繼承的庫(如 Ember.js)時也非常有用。
tsinterface MyType {extend<T>(other: T): this & T;}
ES7 指數運算子
TypeScript 1.7 支援即將到來的 ES7/ES2016 指數運算子:** 和 **=。這些運算子在輸出時將被轉換為使用 Math.pow 的 ES3/ES5 程式碼。
示例
tsvar x = 2 ** 3;var y = 10;y **= 2;var z = -(4 ** 3);
將生成以下 JavaScript 輸出:
jsvar x = Math.pow(2, 3);var y = 10;y = Math.pow(y, 2);var z = -Math.pow(4, 3);
改進了對解構物件字面量的檢查
TypeScript 1.7 使得對帶有物件字面量或陣列字面量初始化器的解構模式的檢查不再那麼死板,變得更加直觀。
當一個物件字面量根據物件繫結模式的隱含型別進行上下文型別推斷時:
- 在物件繫結模式中具有預設值的屬性在物件字面量中變為可選。
- 在物件繫結模式中沒有匹配項的屬性,必須在物件繫結模式中具有預設值,並會被自動新增到物件字面量型別中。
- 在物件字面量中沒有匹配到物件繫結模式的屬性,將會報錯。
當一個數組字面量根據陣列繫結模式的隱含型別進行上下文型別推斷時:
- 在陣列繫結模式中沒有匹配項的元素,必須在陣列繫結模式中具有預設值,並會被自動新增到陣列字面量型別中。
示例
ts// Type of f1 is (arg?: { x?: number, y?: number }) => voidfunction f1({ x = 0, y = 0 } = {}) {}// And can be called as:f1();f1({});f1({ x: 1 });f1({ y: 1 });f1({ x: 1, y: 1 });// Type of f2 is (arg?: (x: number, y?: number) => voidfunction f2({ x, y = 0 } = { x: 0 }) {}f2();f2({}); // Error, x not optionalf2({ x: 1 });f2({ y: 1 }); // Error, x not optionalf2({ x: 1, y: 1 });
支援在目標為 ES3 時使用裝飾器
現在當目標為 ES3 時允許使用裝飾器。TypeScript 1.7 移除了 __decorate 輔助函式中對 ES5 特有方法 reduceRight 的使用。這些更改還以向後相容的方式內聯了對 Object.getOwnPropertyDescriptor 和 Object.defineProperty 的呼叫,透過移除上述 Object 方法的多次重複呼叫,從而優化了 ES5 及後續版本的編譯輸出。