TypeScript 2.3
TypeScript 2.3
发电机(Generators)和 ES5 / ES3 的迭代
首先是一些 ES2016 术语:
迭代器
ES2015 引入Iterator
,这是一个公开的对象的三种方法,next
,return
,和throw
,按如下界面:
interface Iterator<T> {
next(value?: any): IteratorResult<T>;
return?(value?: any): IteratorResult<T>;
throw?(e?: any): IteratorResult<T>;
}
这种迭代器对遍历同步可用值(例如数组的元素或 Map 的键)的迭代很有用。如果支持迭代的对象具有Symbol.iterator
返回Iterator
对象的方法,则称它为“可迭代” 。
迭代器协议还定义了一些 ES2015 功能的目标,例如for..of
扩展运算符以及解构赋值网络中的数组休息。
发电机(Generators)
ES2015 还引入了“发生器”
,这些功能可用于通过Iterator
接口和yield
关键字生成部分计算结果。生成器也可以在内部将调用委托给另一个可迭代的调用yield *
。例如:
function* f() {
yield 1;
yield* [2, 3];
}
新 --downlevelIteration
以前的生成器仅在目标为 ES6 / ES2015 或更高版本时受支持。此外,运行在 Iterator 协议上的构造,例如for..of
仅在 ES6 / ES2015 下的目标阵列上运行时才受支持。
TypeScript 2.3 增加了对发生器和 Iterator 协议的全面支持,用于带有--downlevelIteration
标志的 ES3和ES5 目标。
使用--downlevelIteration
,编译器使用新类型检查并发出行为,如果发现该行为会尝试调用[Symbol.iterator]()
迭代对象上的方法,并在该对象上创建合成数组迭代器(如果不是)。
请注意,这需要在运行时为本机
Symbol.iterator
或Symbol.iterator
填充任何非数组值。
for..of
语句,Array Destructuring 和 Array 中的 Spread 元素,Call 和 New 表达式支持Symbol.iterator
(如果在使用--downlevelIteration
时可用),但是可以在 Array 上使用,即使它在运行时或设计时未定义Symbol.iterator
。
异步迭代
TypeScript 2.3 增加了对当前 TC39 提议
所描述的异步迭代器和生成器的支持。
异步迭代器
异步迭代引入了一个AsyncIterator
类似于Iterator
。不同之处在于以下事实next
,return
以及throw
一个方法AsyncIterator
返回一个Promise
用于迭代结果,而不是结果本身。这使得调用者可以在异步通知中登记进入AsyncIterator
产生值的时间点。一个AsyncIterator
具有以下形状:
interface AsyncIterator<T> {
next(value?: any): Promise<IteratorResult<T>>;
return?(value?: any): Promise<IteratorResult<T>>;
throw?(e?: any): Promise<IteratorResult<T>>;
}
如果支持异步迭代的对象具有Symbol.asyncIterator
返回AsyncIterator
对象的方法,则称其为“可迭代” 。
异步生成器
异步迭代建议
引入“异步发电机”,其是也可以使用,以产生局部计算结果异步函数。异步生成器还可以将调用委托yield*
给可迭代或异步迭代:
async function* g() {
yield 1;
await sleep(100
yield* [2, 3];
yield* (async function *() {
await sleep(100
yield 4;
})(
}
和 Generators 一样,Async Generators 只能是函数声明,函数表达式或类或对象文字的方法。箭头函数不能是异步生成器。异步生成器Promise
除了有效的Symbol.asyncIterator
引用(本机符号或垫片)外,还需要有效的全局实现(本机或 ES2015 兼容的 polyfill )。
for-await-of声明
最后,ES2015 将for..of
语句作为迭代迭代的一种手段。同样,Async Iteration 提议引入了for..await..of
用于遍历异步迭代的语句:
async function f() {
for await (const x of g()) {
console.log(x
}
}
for..await..of
声明仅在异步函数或异步生成器中是合法的。
注意事项
- 请记住,我们对异步迭代器的支持依赖于对
Symbol.asyncIterator
运行时存在的支持。您可能需要填充Symbol.asyncIterator
,这对于简单目的可以如此简单:(Symbol as any).asyncIterator = Symbol.asyncIterator || Symbol.for("Symbol.asyncIterator"
- 如果您尚未拥有它,您还需要包含
esnext
在您的--lib
选项中,以获得AsyncIterator
声明。
- 最后,如果你的目标是 ES5 或 ES3,你还需要设置
--downlevelIterators
标志。
通用参数默认值
TypeScript 2.3 增加了对声明普通类型参数的默认值的支持。
示例
考虑一个创建一个新的HTMLElement
函数,调用它没有参数生成一个Div
; 你可以选择传递一个孩子列表。以前,您必须将其定义为:
declare function create(): Container<HTMLDivElement, HTMLDivElement[]>;
declare function create<T extends HTMLElement>(element: T): Container<T, T[]>;
declare function create<T extends HTMLElement, U extends HTMLElement>(element: T, children: U[]): Container<T, U[]>;
使用通用参数默认值,我们可以将其降低到:
declare function create<T extends HTMLElement = HTMLDivElement, U = T[]>(element?: T, children?: U): Container<T, U>;
通用参数默认遵循以下规则:
- 如果类型参数具有默认值,则该参数被视为可选参数。
- 必需的类型参数不能跟随可选的类型参数。
- 类型参数的缺省类型必须满足 type 参数的约束条件(如果存在)。
- 指定类型参数时,只需要为所需的类型参数指定类型参数。未指定的类型参数将解析为其默认类型。
- 如果指定了默认类型并且推理不能选择候选者,则推断出默认类型。
- 与现有类或接口声明合并的类或接口声明可能引入现有类型参数的默认值。
- 与现有的类或接口声明合并的类或接口声明只要指定了默认值,就可以引入新的类型参数。
新的--strict主选项
添加到 TypeScript 的新检查默认情况下通常是关闭的,以避免破坏现有项目。尽管避免破坏是一件好事,但该策略的缺点是选择最高级别的类型安全性变得越来越复杂,并且这样做需要在每个 TypeScript 版本中明确选择加入操作。使用该--strict
选项,可以选择最大的类型安全性,因为可以通过新版本的编译器报告附加的错误,因为增加了改进的类型检查功能。
新的--strict
编译器选项代表了许多类型检查选项的建议设置。具体而言,指定--strict
对应于指定以下所有选项(并且将来可能包含更多选项):
--strictNullChecks
--noImplicitAny
--noImplicitThis
--alwaysStrict
具体而言,该--strict
选项为上面列出的编译器选项设置默认
值。这意味着仍然可以单独控制选项。例如,
--strict --noImplicitThis false
具有打开除
选项--noImplicitThis
以外
的所有
严格选项的效果。使用这种方案可以表达由除
一些明确列出的选项以外
的所有
严格选项组成的配置。换句话说,现在可以默认最高级别的安全类型,但选择退出某些检查。
从 TypeScript 2.3 开始,tsconfig.json
生成的默认值在该部分tsc --init
包含一个"strict": true
设置"compilerOptions"
。因此,tsc --init
默认启动的新项目将启用最高级别的安全类型。
增强--init输出
随着--strict
默认情况下的设置,tsc --init
具有增强的输出。现在tsconfig.json
生成的默认文件tsc --init
包含一组常用编译器选项及其注释说明。只需取消注释您想要设置的配置即可获得所需的行为; 我们希望新的输出可以简化设置新项目,并随着项目的增长保持配置文件的可读性。
.js 文件中的带有--checkJs错误
默认情况下,TypeScript 编译器不会报告 .js
文件中的任何错误,包括使用--allowJs
。使用 TypeScript 2.3 类型检查错误也可以在.js
文件中报告--checkJs
。
您可以通过添加// @ts-nocheck
评论来跳过检查某些文件; 相反,您可以选择只检查几个.js
文件,通过添加// @ts-check
评论而不设置--checkJs
。您也可以通过// @ts-ignore
在上一行添加来忽略特定行上的错误。
.js
仍然检查文件以确保它们只包含标准的 ECMAScript 功能; 类型注释只允许在.ts
文件中被标记为.js
文件中的错误。JSDoc 注释可用于向 JavaScript 代码添加一些类型信息,请参阅 JSDoc 支持文档以获取有关受支持的 JSDoc 结构的更多详细信息。
请参阅类型检查 JavaScript 文档
以获取更多详细信息。