TypeScript 2.2
TypeScript 2.2
支持混合类
TypeScript 2.2 添加了对 ECMAScript 2015 mixin 类模式的支持(请参阅 MDN Mixin 描述
和带有 JavaScript 类的“Real”Mixins
以获取更多详细信息)以及将 mixin 构造签名与交集类型中的常规构造签名组合在一起的规则。
首先是一些术语
一个混入构造型是指具有与类型的单个参数其余的单个构建签名类型any[]和类似对象的返回类型。例如,给定一个类似于对象的类型X,new (...args: any[]) => X是一个带有实例类型的mixin构造函数类型X。
一个混合类
是一类声明或表达式extends
的类型参数类型的表达式。以下规则适用于 mixin 类声明:
extends
表达式的类型参数类型必须被约束为一个 mixin 构造函数类型。
- mixin 类的构造函数(如果有的话)必须具有一个
any[]
类型的 rest 参数,并且必须使用 spread 运算符将这些参数作为参数传递给super(...args)
调用。
给定具有X
约束的T
参数类型的表达式Base
,混合类将class C extends Base {...}
像处理Base
类型一样进行处理,结果X
类型为typeof C & T
交集。换句话说,mixin 类表示为 mixin 类构造函数类型和参数基类构造函数类型之间的交集。
当获得包含mixin构造函数类型的交集类型的构造签名时,mixin构造签名将被丢弃,并且它们的实例类型将被混合到交集类型中其他构造签名的返回类型中。例如,交集类型{ new(...args: any[]) => A } & { new(s: string) => B }具有单个构造签名new(s: string) => A & B。
将所有上述规则放在一个示例中
class Point {
constructor(public x: number, public y: number) {}
}
class Person {
constructor(public name: string) {}
}
type Constructor<T> = new(...args: any[]) => T;
function Tagged<T extends Constructor<{}>>(Base: T) {
return class extends Base {
_tag: string;
constructor(...args: any[]) {
super(...args
this._tag = "";
}
}
}
const TaggedPoint = Tagged(Point
let point = new TaggedPoint(10, 20
point._tag = "hello";
class Customer extends Tagged(Person) {
accountBalance: number;
}
let customer = new Customer("Joe"
customer._tag = "test";
customer.accountBalance = 0;
Mix
in 类可以通过在类型参数的约束中指定构造体签名返回类型来约束它们可以混入的类的类型。例如,下面的WithLocation
函数实现了一个子类工厂,它将一个getLocation
方法添加到满足该Point
接口的任何类(即具有类型x
和y
属性的number
类)。
interface Point {
x: number;
y: number;
}
const WithLocation = <T extends Constructor<Point>>(Base: T) =>
class extends Base {
getLocation(): [number, number] {
return [this.x, this.y];
}
}
object 类型
TypeScript 没有表示非基本类型,即不是任何事情型number
,string
,boolean
,symbol
,null
,或undefined
。输入新的object
类型。
使用object
类型,API 像Object.create
可以更好地表示 。例如:
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 改进了对表达式中可空操作数的检查。具体来说,这些现在被标记为错误:
- 如果运算
+
符的任何一个操作数都是可以为空的,并且这两个操作数都不是类型any
或string
。
- 如果一个操作数-,*,**,/,%,<<,>>,>>>,&,|,或^运算符可为空。
- 如果一个操作数<,>,<=,>=,或in运算符可为空。
- 如果操作
instanceof
运算符的右操作数是可空的。
- 如果一个操作数
+
,-
,~
,++
,或--
一元运算符可为空。
如果操作数的类型是null
或者 undefined
或者包含null
或者联合类型,则操作数被认为是可空的undefined
。需要注意的是联合类型情况下,只只发生在--strictNullChecks
模式,因为null
和undefined
在经典型检查模式工会消失。
具有字符串索引签名的类型的虚线属性
带有字符串索引签名的类型可以使用[]
符号进行索引,但不允许使用该符号.
。应该允许从 TypeScript 2.
2 开始。
interface StringMap<T> {
[x: string]: T;
}
const map: StringMap<number>;
map["prop1"] = 1;
map.prop2 = 2;
这仅适用于具有显式
字符串索引签名的类型。使用.
表示法访问类型上的未知属性仍然是错误的。
支持 JSX 元素子元素上的扩展运算符
TypeScript 2.2 增加了对在 JSX 元素上使用传播的支持。
示例
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
.js
即使文件包含 JSX 语法,React-native 构建管道也期望所有文件都具有扩展名。新的--jsx
值react-native
将继续输出文件中的 JSX 语法,但给它一个.js
扩展。