TypeScript 1.4 先睹为快,联合类型和类型保护

jopen 7年前

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