TypeScript/doc/release-notes/TypeScript 2.2.md
2017-02-07 08:49:52 +08:00

4.1 KiB
Raw Blame History

TypeScript 2.2

object类型

TypeScript没有表示非基本类型的类型即不是number | string | boolean | symbol | null | undefined的类型。一个新的object类型登场。

使用object类型,可以更好地表示类似Object.create这样的API。例如

declare function create(o: object | null): void;

create({ prop: 0 }); // OK
create(null); // OK

create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error

支持new.target

new.target元属性是ES2015引入的新语法。当通过new构造函数创建实例时,new.target的值被设置为对最初用于分配实例的构造函数的引用。如果一个函数不是通过new构造而是直接被调用,那么new.target的值被设置为undefined

当在类的构造函数中需要设置Object.setPrototypeOf__proto__时,new.target就派上用场了。在NodeJS v4及更高版本中继承Error类就是这样的使用案例。

示例

class CustomError extends Error {
    constructor(message?: string) {
        super(message); // 'Error' breaks prototype chain here
        Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
    }
}

生成JS代码

var CustomError = (function (_super) {
  __extends(CustomError, _super);
  function CustomError() {
    var _newTarget = this.constructor;
    var _this = _super.apply(this, arguments);  // 'Error' breaks prototype chain here
    _this.__proto__ = _newTarget.prototype; // restore prototype chain
    return _this;
  }
  return CustomError;
})(Error);

new.target也适用于编写可构造的函数例如

function f() {
  if (new.target) { /* called via 'new' */ }
}

编译为:

function f() {
  var _newTarget = this && this instanceof f ? this.constructor : void 0;
  if (_newTarget) { /* called via 'new' */ }
}

更好地检查表达式的操作数中的null / undefined

TypeScript 2.2改进了对表达式中可空操作数的检查。具体来说,这些现在被标记为错误:

  • 如果+运算符的任何一个操作数是可空的,并且两个操作数都不是anystring类型。
  • 如果-***/<<>>>>>, &, |^运算符的任何一个操作数是可空的。
  • 如果<><=>=in运算符的任何一个操作数是可空的。
  • 如果instanceof运算符的右操作数是可空的。
  • 如果一元运算符+-~++或者--的操作数是可空的。

如果操作数的类型是nullundefined或者包含nullundefined的联合类型,则操作数视为可空的。注意:包含nullundefined的联合类型只会出现在--strictNullChecks模式中,因为常规类型检查模式下nullundefined在联合类型中是不存在的。

字符串索引签名类型的点属性

具有字符串索引签名的类型可以使用[]符号访问,但不允许使用.符号访问。从TypeScript 2.2开始两种方式都允许使用。

interface StringMap<T> {
    [x: string]: T;
}

const map: StringMap<number>;

map["prop1"] = 1;
map.prop2 = 2;

这仅适用于具有显式字符串索引签名的类型。在类型使用上使用.符号访问未知属性仍然是一个错误。

支持在JSX元素children上使用扩展运算符

TypeScript 2.2增加了对在JSX元素children上使用扩展运算符的支持。更多详情请看facebook/jsx#57

示例

function Todo(prop: { key: number, todo: string }) {
    return <div>{prop.key.toString() + prop.todo}</div>;
}

function TodoList({ todos }: TodoListProps) {
    return <div>
        {...todos.map(todo => <Todo key={todo.id} todo={todo.todo} />)}
    </div>;
}

let x: TodoListProps;

<TodoList {...x} />

新的jsx: react-native

React-native构建管道期望所有文件都具有.js扩展名即使该文件包含JSX语法。新的--jsx编译参数值react-native将在输出文件中坚持JSX语法但是给它一个.js扩展名。