TypeScript 2.0

完整的破坏性改动列表请到这里查看:breaking change issues.

对函数或类表达式的捕获变量不进行类型细化(narrowing)

类型细化不会在函数,类和lambda表达式上进行。

例子

  1. var x: number | string;
  2. if (typeof x === "number") {
  3. function inner(): number {
  4. return x; // Error, type of x is not narrowed, c is number | string
  5. }
  6. var y: number = x; // OK, x is number
  7. }

编译器不知道回调函数什么时候被执行。考虑下面的情况:

  1. var x: number | string = "a";
  2. if (typeof x === "string") {
  3. setTimeout(() => console.log(x.charAt(0)), 0);
  4. }
  5. x = 5;

x.charAt()被调用的时候把x的类型当作string是错误的,事实上它确实不是string类型。

推荐

使用常量代替:

  1. const x: number | string = "a";
  2. if (typeof x === "string") {
  3. setTimeout(() => console.log(x.charAt(0)), 0);
  4. }

泛型参数会进行类型细化

例子

  1. function g<T>(obj: T) {
  2. var t: T;
  3. if (obj instanceof RegExp) {
  4. t = obj; // RegExp is not assignable to T
  5. }
  6. }

推荐可以把局部变量声明为特定类型而不是泛型参数或者使用类型断言。

只有get而没有set的存取器会被自动推断为readonly属性

例子

  1. class C {
  2. get x() { return 0; }
  3. }
  4. var c = new C();
  5. c.x = 1; // Error Left-hand side is a readonly property

推荐

定义一个不对属性写值的setter。

在严格模式下函数声明不允许出现在块(block)里

在严格模式下这已经是一个运行时错误。从TypeScript 2.0开始,它会被标记为编译时错误。

例子

  1. if( true ) {
  2. function foo() {}
  3. }
  4. export = foo;

推荐

使用函数表达式代替:

  1. if( true ) {
  2. const foo = function() {}
  3. }

TemplateStringsArray现是是不可变的

ES2015模版字符串总是将它们的标签以不可变的类数组对象进行传递,这个对象带有一个raw属性(同样是不可变的)。TypeScript把这个对象命名为TemplateStringsArray

便利的是,TemplateStringsArray可以赋值给Array<string>,因此你可以利用这个较短的类型来使用标签参数:

  1. function myTemplateTag(strs: string[]) {
  2. // ...
  3. }

然而,在TypeScript 2.0,支持用readonly修饰符表示这些对象是不可变的。这样的话,TemplateStringsArray 就变成了不可变的,并且不再可以赋值给string[]

推荐

直接使用TemplateStringsArray(或者使用ReadonlyArray<string>)。