严格函数类型
TypeScript 2.6引入了新的类型检查选项,--strictFunctionTypes。--strictFunctionTypes选项是--strict系列选项之一,也就是说 --strict模式下它默认是启用的。你可以通过在命令行或tsconfig.json中设置--strictFunctionTypes false来单独禁用它。
--strictFunctionTypes启用时,函数类型参数的检查是_抗变(contravariantly)_而非_双变(bivariantly)_的。关于变体 (variance) 对于函数类型意义的相关背景,请查看协变(covariance)和抗变(contravariance)是什么?。
这一更严格的检查应用于除方法或构造函数声明以外的所有函数类型。方法被专门排除在外是为了确保带泛型的类和接口(如Array<T>)总体上仍然保持协变。
考虑下面这个 Animal 是 Dog 和 Cat 的父类型的例子:
ts
第一个赋值语句在默认的类型检查模式中是允许的,但是在严格函数类型模式下会被标记错误。 通俗地讲,默认模式允许这么赋值,因为它_可能是_合理的,而严格函数类型模式将它标记为错误,因为它不能_被证明_合理。 任何一种模式中,第三个赋值都是错误的,因为它_永远不_合理。
用另一种方式来描述这个例子则是,默认类型检查模式中T在类型(x: T) => void是_双变的_(也即协变_或_抗变),但在严格函数类型模式中T是_抗变_的。
例子
ts
现在第一个赋值是错误的。更明确地说,Comparer<T>中的T因为仅在函数类型参数的位置被使用,是抗变的。
另外,注意尽管有的语言(比如C#和Scala)要求变体标注(variance annotations)(out/in 或 +/-),而由于TypeScript的结构化类型系统,它的变体是由泛型中的类型参数的实际使用自然得出的。
注意:
启用--strictFunctionTypes时,如果compare被声明为方法,则第一个赋值依然是被允许的。 更明确的说,Comparer<T>中的T因为仅在方法参数的位置被使用所以是双变的。
ts
TypeScript 2.6 还改进了与抗变位置相关的类型推导:
ts
这上面所有T的推断都来自抗变的位置,由此我们得出T的_最普遍子类型_。 这与从协变位置推导出的结果恰恰相反,从协变位置我们得出的是_最普遍超类型_。
缓存模块中的标签模板对象
TypeScript 2.6修复了标签字符串模板的输出,以更好地遵循ECMAScript标准。 根据ECMAScript 标准,每一次获取模板标签的值时,应该将_同一个_模板字符串数组对象 (同一个 TemplateStringArray) 作为第一个参数传递。 在 TypeScript 2.6 之前,每一次生成的都是全新的模板对象。 虽然字符串的内容是一样的,这样的输出会影响通过识别字符串来实现缓存失效的库,比如 lit-html。
例子
ts
编译后的代码:
js
注意:这一改变引入了新的工具函数,
__makeTemplateObject; 如果你在搭配使用--importHelpers和tslib,需要更新到 1.8 或更高版本。
本地化的命令行诊断消息
TypeScript 2.6 npm包加入了13种语言的诊断消息本地化版本。 命令行中本地化消息会在使用--locale选项时显示。
例子
俄语显示的错误消息:
bash
中文显示的帮助信息:
bash
通过 ’// @ts-ignore’ 注释隐藏 .ts 文件中的错误
TypeScript 2.6支持在.ts文件中通过在报错一行上方使用// @ts-ignore来忽略错误。
例子
ts
// @ts-ignore注释会忽略下一行中产生的所有错误。 建议实践中在@ts-ignore之后添加相关提示,解释忽略了什么错误。
请注意,这个注释仅会隐藏报错,并且我们建议你_极少_使用这一注释。
更快的 tsc --watch
TypeScript 2.6 带来了更快的--watch实现。 新版本优化了使用ES模块的代码的生成和检查。 在一个模块文件中检测到的改变_只_会使改变的模块,以及依赖它的文件被重新生成,而不再是整个项目。 有大量文件的项目应该从这一改变中获益最多。
这一新的实现也为tsserver中的监听带来了性能提升。 监听逻辑被完全重写以更快响应改变事件。
只写的引用现在会被标记未使用
TypeScript 2.6加入了修正的--noUnusedLocals和--noUnusedParameters编译选项实现。 只被写但从没有被读的声明现在会被标记未使用。
例子
下面n和m都会被标记为未使用,因为它们的值从未被_读取_。之前 TypeScript 只会检查它们的值是否被_引用_。
ts
另外仅被自己内部调用的函数也会被认为是未使用的。
例子
ts