TypeScript 1.4 先睹為快,聯合類型和類型保護
TypeScript 1.3 剛剛發布沒兩天,我們繼續給 TypeScript 添加更多類型系統和來自 ECMAScript 6 的特性。讓我們先來看看下一個版本 TypeScript 1.4 中將會提供的新特性。這些這特性都可以通過 Github 倉庫中的 master 主分支來獲取。
這些新的特性讓我們可以在運行時簡單而且精確的處理變量和表達式可能有不同的類型,同時還可以幫助減少顯式類型注解、類型診斷和使用 any 類型的需要。類型定義文件 (.d.ts) 作者可使用這些特性來更精確的描述外部庫。對于開發編譯器的人員來說,你將會注意到我們已經在編譯器中使用這些新特性了。
聯合類型 Union types
聯合類型是用來表達一個值具有多種不同類型的強大方式。例如你可能會使用一個 API 用于執行一個程序,這個程序接受命令行參數作為 string 或者是 string[] ,那么你可以這樣寫:
interface RunOptions { program: string; commandline: string[]|string; }
賦值給聯合類型的語句非常直觀,你可以給聯合類型賦值任何一個聯合類型的成員:
var opts: RunOptions = /* ... */; opts.commandline = '-hello world'; // OK opts.commandline = ['-hello', 'world']; // OK opts.commandline = [42]; // Error, number is not string or string[]
當從一個聯合類型中讀取是,你可以看到它們分享的所有屬性:
if(opts.commandline.length === 0) { // OK, string and string[] both have 'length' property console.log("it's empty"); }
使用類型保護,你可以輕松處理各種聯合類型:
function formatCommandline(c: string[]|string) { if(typeof c === 'string') { return c.trim(); } else { return c.join(' '); } }
類型保護 Type Guards
JavaScript 一個常用的方式就是使用 typeof 或者 instanceof 來在運行時檢查一個表達式的類型。TypeScript 現在可在 if 塊中理解這種情況。
使用 typeof 來測試一個變量:
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
使用 instanceof 來處理類和聯合類型:
class Dog { woof() { } } class Cat { meow() { } } var pet: Dog|Cat = /* ... */; if(pet instanceof Dog) { pet.woof(); // OK } else { pet.woof(); // Error }
更嚴格的泛型 Stricter Generics
聯合類型可以用來表示多重類型場景,因此我們有必要改進泛型的嚴謹性。像之前這樣的代碼編譯是沒有任何錯誤的:
function equal<T>(lhs: T, rhs: T): boolean { return lhs === rhs; } // Previously: No error // New behavior: Error, no best common type between 'string' and 'number' var e = equal(42, 'hello');
更好的類型推斷 Better Type Inference
聯合類型同時也允許對數組以及集合中的值做更好的類型推斷:
var x = [1, 'world']; // x: Array<string|number> x[0] = 'hello'; // OK x[0] = false; // Error, boolean is not string or number
類型別名 Type Aliases
你可以使用 type 關鍵字來定義一個類型的別名:
type PrimitiveArray = Array<string|number|boolean>; type MyNumber = number; type NgScope = ng.IScope; type Callback = () => void;
類型別名和原始類型完全一致,它只是一個可選的名稱而已。
在以后的文章中我們還將介紹在新版本的 TypeScript 中集成的 ECMAScript 6 的特性。
來自:MSDN