本文为公众号“TypeScript社区(QQ 群号 390037547)”原创翻译,转载请注明出处!否则追究法律责任!
TypeScript 3.2 正式版于 2018 年 11 月 29 日发布。此版本新增特性及变更事项如下:
• 严格的 bind、call 和 apply
• 泛型类型上的对象展开操作
• 泛型类型上的对象剩余操作
• 基于 Node.js 的 tsconfig.json 继承解决方案
• 使用“--showConfig”来对 tsconfig.json 进行诊断
• BigInt
• JavaScript 中的 Object.defineProperty 声明
• 错误信息改进
• 标记化联合类型的类型收窄改进
• 编辑改进
• 破坏性变更和弃用项
• NuGet 和 Visual Studio 2015 用户注意事项
• 下一步是什么
下面为大家带来 TypeScript 官方博客的翻译:
TypeScript 3.2 is here today!
今天 TypeScript 3.2 到来了!
If you’re unfamiliar withTypeScript, it’s a language that brings static type-checking to JavaScript so that you can catch issues before you even run your code – or before you even save your file. It also includes the latest JavaScript features from the ECMAScript standard on older browsers and runtimes by compiling those features into a form that they understand. But beyond type-checking and compiling your code, TypeScript also provides tooling in your favorite editor so that you can jump to the definition of any variable, find who’s using a given function, and automate refactorings and fixes to common problems. TypeScript even provides this for JavaScript users (and can also type-check JavaScript code typed withJSDoc), so if you’ve used editors like Visual Studio or Visual Studio Code on a .js file, TypeScript is powering that experience.
如果你不熟悉 TypeScript,它是一门语言,为JavaScript 带来了静态类型检查以便你能够在运行代码前甚至是保存文件前捕获问题。它还包括来自 ECMAScript 标准的最新的 JavaScript 特性,这些特性能够运行在老版本的浏览器或运行时上——通过将这些新特性编译为老版本浏览器或运行时理解的形式来实现。但是,除了类型检查和编译你的代码,TypeScript 还提供了你最喜欢的编辑器中的工具以便你可以跳转到任何变量的定义位置,找到谁正在使用某个函数,以及自动地重构和修复常见的问题。TypeScript 甚至为 JavaScript用户提供了这些功能特性(也可以对使用 JSDoc类型化后的 JavaScript 代码进行类型检查),所以如果你使用如 Visual Studio 或者 Visual Studio Code 这样的编辑器来编辑 js 文件,TypeScript 正在为这些体验提供动力。
To get started with the language itself, check out typescriptlang.org to learn more.
要开始使用这个语言,请查看这里typescriptlang.org 以了解更多信息。
But if you want to try TypeScript 3.2 out now, you can get it through NuGet or via npm by running
但是如果你想要现在就尝试 TypeScript 3.2,你可以通过 NuGet 或者通过npm(通过运行以下命令)来获取它:
npm install -g typescript
You can also get editor support for
你也可以获得对以下编辑器的支持:
• Visual Studio 2017 (for version 15.2 or later).
Visual Studio 2017(版本 15.2 或更高版本)。
• Visual Studio 2015 (which requires update 3).
Visual Studio 2015(需要更新版 3)。
• For Visual Studio Code by installing the Insiders release until the full release provides it.
对于 Visual Studio Code,在提供完整发布版之前通过安装预览发布版来获取。
• Sublime Text 3 via PackageControl.
Sublime Text 3 通过 PackageControl 获取。
Other editors may have different update schedules, but should all have TypeScript available soon.
其它编辑器会有不同的更新计划,但都会很快就有可用的 TypeScript。
We have some important information below for NuGet users and Visual Studio 2015 users, so please continue reading if you use either product.
下面我们有一些对 NuGet 和 Visual Studio 2015用户而言非常重要的信息,所以如果你使用这两个产品,请继续阅读。
Below we have a bit about what’s new in 3.2.
下面是关于 3.2 中新增的内容。
• strictBindCallApply
严格的 bind、call 和 apply
• Object spread on generic types
泛型类型上的对象展开
• Object rest on generic types
泛型类型上的对象剩余操作
• Node.js-based resolution for tsconfig.json inheritance
基于 Node.js 的 tsconfig.json 继承解决方案
• Diagnosing tsconfig.json with --showConfig
使用“--showConfig”来对 tsconfig.json 进行诊断
• BigInt
大整数
• Object.defineProperty declarations in JavaScript
JavaScript 中的 Object.defineProperty 声明
• Error message improvements
错误信息改进
• Improved narrowing for tagged unions
标记式联合类型的类型收窄改进
• Editing improvements
编辑改进
• Breaking changes and deprecations
破坏性变更和弃用项
A note for NuGet and Visual Studio 2015 users
给 NuGet 和 VisualStudio 2015 用户的提示
• What’s next
下一步是什么
strictBindCallApply
严格的 bind、call 和 apply
As you might’ve guessed from the title of this section, TypeScript 3.2 introduces stricter checking for bind, call, and apply. But what does that mean?
正如你可能从这个标题所猜测的那样,TypeScript3.2 引入了对 bind、call 和 apply 更严格的检查。但那意味着什么呢?
Well, in JavaScript, bind, call, and apply are methods on functions that allow us to do things like bind this and partially apply arguments, call functions with a different value for this, and call functions with an array for their arguments.
在 JavaScript 中,bind、call 和 apply 是在函数上的方法,它们允许我们做这些事情——绑定 this并应用部分参数,使用一个不同的 this 值来调用函数,以及使用承载函数参数的数组来调用函数。
Unfortunately, in its earlier days, TypeScript lacked the power to model these functions, and bind, call, and apply were all typed to take any number of arguments and returned any. Additionally, ES2015’s arrow functions and rest/spread arguments gave us a new syntax that made it easier to express what some of these methods do – and in a more efficient way as well.
不幸的是,在早些时期,TypeScript 缺少对这些函数建模的能力,并且 bind、call 和 apply 都被类型化为接收任意数量的参数并返回 any 的函数。另外,ES2015 的箭头函数和剩余/展开参数带给我们一个新的语法,它使得表达这些方法是做什么的变得更容易也更高效。
Still, demand to model these patterns in a type-safe way led us to revisit this problem recently. We realized that two features opened up the right abstractions to accurately type bind, call,and apply without any hard-coding:
尽管如此,要求以类型安全的方式对这些模式进行建模,使得我们最近又重新审视了这个问题。我们意识到两个特性开辟了正确的抽象来精确地标注 bind、call 和 apply 的类型而无需任何硬编码:
- this parameter types from TypeScript 2.0
来自 TypeScript 2.0 的 this 参数类型
- Modeling parameter lists with tuple types from TypeScript 3.0
来自 TypeScript 3.0 的使用元组类型模拟参数列表
Combined, the two of of them can ensure our uses of bind, call, and apply are more strictly checked when we use a new flag called strictBindCallApply. When using this new flag,the methods on callable objects are described by a new global type called CallableFunction which declares stricter versions of the signatures for bind, call,and apply. Similarly, any methods on constructable (but not callable) objects are described by a new global type called NewableFunction.
结合起来,当我们使用一个新的称作 strictBindCallApply 的标志时,这两项能够确保我们对 bind、call 和 apply 的使用能够被严格地检查。当使用这个新标志时,可调用地对象上的方法被一个被称为 CallableFunction 的全局类型所描述,该类型声明了 bind、call 和 apply 签名的更严格的版本。类似的,可构建(但不是可调用)对象上的任何方法都是被一个被称为 NewableFunction 的全局类型所描述。
As an example, we can look at how Function.prototype.apply acts under this behavior:
作为例子,我们可以看到在这个行为之下 Function.prototype.apply 是如何表现的:
function foo(a:number, b:string):string{
return a + b;
}
let a = foo.apply(undefined, [10]);// error: too few argumnts
let b = foo.apply(undefined, [10, 20]);// error: 2nd argument is anumber
let c = foo.apply(undefined,[10, "hello", 30]); // error: too many arguments
let d = foo.apply(undefined,[10, "hello"]);// okay! returns a string
Needless to say, whether you do any sophisticated metaprogramming, or you use simplepatterns like binding methods in your class instances (this.foo=this.foo.bind(this)), this feature can help catch a lot of bugs. For more details, you can check out the original pull request here.
不用说,无论你是做复杂的元编程,或者是使用简单的模式,如在类实例里绑定方法(如 this.foo = this.foo.bind(this)),这个特性可以帮助捕获许多的 bug。更多详细信息,你可以在这里查看原始的拉取请求。
Caveats
注意事项
One caveat of this new functionality is that due to certain limitations, bind, call, and apply can’t yet fully model generic functions or functions that have overloads.When using these methods on a generic function, type parameters will be substituted with the empty object type ({}), and when used on a function with overloads, only the last overload will ever be modeled.
这个新功能特性有一点需要注意的是,因为某些限制,bind、call 和 apply 不能完全地对泛型函数或者重载函数进行建模。当在一个泛型函数上使用这些方法时,类型参数将会被空对象({})替代,而当在一个重载函数上使用时,只对最后一个重载进行建模。
Objects pread on generic types
泛型类型上的对象展开
JavaScript supports a handy way of copying existing properties from an existing object into a new one called “spreads”. To spread an existing object into a new object, you define an element with three consecutive periods (...) like so:
JavaScript支持一种简便的方式来从一个现有的对象上复制属性到一个新的对象中,这种方式叫做“展开”。要将一个现有对象展开到一个新的对象中,你要定义一个这样带三个连续句点(...)的元素:
let person = { name:"Daniel", location:"New York City"};
// My secret revealed, I have two clones!
let shallowCopyOfPerson = { ...person };
let shallowCopyOfPersonWithDifferentLocation = {...person, location:"Seattle"};
TypeScript does a pretty good job here when it has enough information about the type. The type system closely tries to model the behavior of spreads and overwrites new properties, tries to ignore methods, etc. But unfortunately up until now it wouldn’t work with generics at all.
当有足够多的关于类型的信息时,TypeScript 能工作得很好。类型系统尝试模拟展开行为并覆写新的属性,尝试忽略方法等。但不幸的是,直到目前它仍完全无法用于泛型。
function merge<T,U>(x: T,y:U) {
// Previously an error!
return { ...x, ...y };
}
This was an error because we had no way to express the return type of merge. There was no syntax (nor semantics) that could express two unknown types being spread into a new one.
这曾经是一个错误因为我们无法表示 merge 的返回类型。没有语法(或者语义)能够表示两个未知类型展开到一个新的类型中。
We could have come up with a new concept in the type system called an “object spread type”, and in fact we had a proposal for exactly that. Essentially this would be a new type operator that looks like { ...T,...U } to reflect the syntax of an object spread.
我们可能会想出一个新的概念,在类型系统中称为“对象展开类型”,事实上我们的确有那么个提案。实质上,它会成为一个新的,看起来像“{...T,...U }” 这样的类型操作符以反映一个对象展开的语法。
When both T and U are known, that type would flatten down to some new object type.
当T 和 U 都是未知的时候,那个类型将会扁化为某些新的对象类型。
However, this is pretty complex and requires adding new rules to type relationships and inference. While we explored several different avenues, we recently arrived at two conclusions:
然而,这是相当复杂的,且需要添加新的规则到类型关系和推断中。当我们考察了几种不同的方式后,我们最近得到两个结论:
- For most uses of spreads in JavaScript, users were fine modeling the behavior with intersection types (i.e. Foo & Bar).
JavaScript中使用的大多数展开,用户可以使用交叉类型(例如 Foo& Bar)来模拟该行为。
- Object.assign – a function that exhibits most of the behavior of spreading objects – is already modeled using intersection types, and we’ve seen very little negative feedback around that.
Object.assign——一个展示了展开对象的绝大多数行为的函数——已经使用交叉类型进行模拟,并且我们未看到关于它的负面反馈。
Given that intersections model the common cases, and that they’re relatively easy to reason about for both users and the type system, TypeScript 3.2 now permits object spreads on generics and models them using intersections:
鉴于交叉类型模拟了常见的情形,且对于用户和类型系统而言相对容易推理,TypeScript 3.2 现在允许对泛型进行对象展开并使用交叉类型来模拟它们:
// Returns 'T & U'
function merge<T,U>(x:T, y:U) {
return{ ...x, ...y };
}
// Returns '{ name: string, age: number,greeting: string } & T'
function foo<T>(obj:T) {
let person = {
name: "Daniel",
age:26
};
return { ...person, greeting:"hello", ...obj };
}
Object rest on generic types
泛型类型上的对象剩余操作
Object rest patterns aresort of the dual of object spreads. Instead of creating a new object with some extra/overridden properties, it creates a new object that lacks some specified properties.
对象剩余模式有点像双重的对象展开。它创建一个新的缺少某些特定属性的对象,而不是创建一个新的带有额外的/被覆盖的属性的对象。
let { x, y, z, ...rest } = obj;
In the above, the most intuitive way to look at this code is that rest copies over all the properties from obj apart from x, y, and z. For the same reason as above, because we didn’t have a good way to describe the type of rest when obj is generic, we didn’t support this for a while.
如上,最直观的看待这个代码的方式是 rest 从 obj 复制除了 x、y 和 z 之外的所有属性。由于上述相同的原因,当 obj 是泛型时,我们没有一个好的方式来描述 rest 的类型,我们暂时不支持这个。
Here we also considered a new rest operator, but we saw we already had the facilities for describing the above: our Pick and Exclude helper types in lib.d.ts To reiterate, ...rest basically picks off all ofthe properties on obj except for x, y, and z in the following example:
这里我们也考虑过一个新的剩余运算符,但我们看到我们已经有了描述上述情形的装备:lib.d.ts 中的 Pick 和 Exclude 帮助器类型。为了重申这一点,下面例子中 ...rest 拾取 obj 中除了 x、y 和 z 的所有属性:
interface XYZ{ x:any; y:any; z:any; }
function dropXYZ<T extends XYZ>(obj:T) {
let { x, y, z, ...rest } = obj;
return rest;
}
If we want to consider the properties of T (i.e. keyof T) except for x, y, and z, we can write Exclude<keyof T, "x" | "y" | "z">. We then want to pick those properties back off of the original type T, which gives us
如果我们要考虑 T(例如,keyof T)中除了 x、y 和 z 之外的属性,我们可以写 Exclude<keyof T, "x" | "y" |"z">。我们然后想要把原来的那个类型 T 的那些属性取回来,这让我得到:
Pick<T, Exclude<keyof T, "x" |"y" | "z">>`.
While it’s not the most beautiful type (hey, I’m no George Clooney myself), we can wrap it in a helper type like DropXYZ:
虽然它不是最好看的类型,我们可以把它包装到一个帮助器类型中,如 DropXYZ:
interface XYZ { x:any; y:any; z:any; }
type DropXYZ<T> = Pick<T, Exclude<keyof T, keyof XYZ>>;
function dropXYZ<T extends XYZ>(obj:T):DropXYZ<T> {
let { x, y, z, ...rest } = obj;
return rest;
}
Configuration inheritance via node_modules packages
通过 node_modules 包实现配置继承
For a long time TypeScript has supported extending tsconfig.json files using the extends field.
很早以前 TypeScript 就已经支持使用 extends 字段来扩展 tsconfig.json 文件。
{
"extends":"../tsconfig-base.json",
"include": ["./*/"]
"compilerOptions": {
// Override certain options on a project-by-projectbasis.
"strictBindCallApply":false,
}
}
This feature is very useful to avoid duplicating configuration which can easiy fall out of sync, but it really works best when multiple projects are co-located in the same respository so that each project can reference a common “base” tsconfig.json.
这个特性对于避免重复配置是非常有用的,这些重复的配置很容易失去同步,但是当多个项目共同位于同一个储存库中时,它确实是最有效的,这样每个项目都可以引用一个通用的基础 tsconfig.json。
But for some teams, projects are written and published as completely independent packages. Those projects don’t have a common file they can reference, so as a workaround, users could create a separate package and reference that:
但是对于某些团队,项目是作为完全独立的包来编写和发布的。那些项目没有一个通用的文件可以供他们引用,因此,作为一个变通方案,用户可以创建一个单独的包并引用它:
{
"extends": "../node_modules/@my-team/tsconfig-base/tsconfig.json",
"include": ["./*/"]
"compilerOptions": {
// Override certain options on a project-by-projectbasis.
"strictBindCallApply":false,
}
}
However,climbing up parent directories with a series of leading ../s and reaching directly into node_modules to grab a specific file feels unwieldy.
然而,通过一系列前导的 ../ 爬升到父目录并进入到 node_modules 来获取特定的文件显得很粗笨。
TypeScript 3.2 now resolves tsconfig.jsons from node_modules. When using a bare path for the "extends" field in tsconfig.json,TypeScript will dive into node_modules packages for us.
TypeScript 3.2 现在从 node_modules 中解析 tsconfig.json。当在 tsconfig.json 中为“extends”字段使用一个裸路径(没有前导的“../”)时,TypeScript 将会为我们潜入到 node_modules 包中。
{
"extends":"@my-team/tsconfig-base",
"include": ["./*/"]
"compilerOptions": {
// Override certain options on a project-by-projectbasis.
"strictBindCallApply":false,
}
}
Here,TypeScript will climb up node_modules folders looking for a @my-team/tsconfig-base package. For each of those packages, TypeScript will first check whether package.json contains a "tsconfig" field, and if it does,TypeScript will try to load a configuration file from that field. If neither exists, TypeScript will try to read from a tsconfig.json at the root. This is similar to the lookup process for .js files in packages that Node uses, and the .d.ts lookup process that TypeScript already uses.
在这里,TypeScript 将会爬升到 node_modules 文件夹查找一个叫做 @my-team/tsconfig-base 的包。对于每一个包,TypeScript 将会首先检查 package.json 是否包含一个“tsconfig”字段,如果有,TypeScript 将会尝试从根据那个字段加载配置文件。如果都没有,TypeScript 将会尝试从根目录的 tsconfig.json 读取。这和查找 Node 使用的 .js 文件的过程以及查找TypeScript 已经使用的 .d.ts 文件的过程相似。
This feature can be extremely useful for bigger organizations, or projects with lots of distributed dependencies.
这个特性对于大型组织或者有许多分布式依赖的项目特别的有用。
Diagnosing tsconfig.json with --showConfig
使用 --showConfig 来诊断 tsconfig.json
tsc, the TypeScript compiler, supports a new flag called --showConfig. When running tsc --showConfig, TypeScript will calculate the effective tsconfig.json (after calculating options inherited from the extends field) and print that out.This can be useful for diagnosing configuration issues in general.
TypeScript 编译器 tsc 支持新的称作 --showConfig 的标志。当运行 tsc --showConfig 时,TypeScript 将会计算有效的 tsconfig.json(在计算继承于 extends 字段的选项之后)并把它们打印出来。一般这对于诊断配置问题很有用。
BigInt
大整数
BigInts are part of an upcoming proposal in ECMAScript that allow us to model theoretically arbitrarily large integers. TypeScript 3.2 brings type-checking for BigInts, as well as support for emitting BigInt literals when targeting esnext.
BigInt 是即将到来的 ECMAScript提案中的一部分,它允许我们模拟理论上任意大的整数。当将编译目标设定为 esnext 时,TypeScript3.2 为BigInt 带来了类型检查以及支持生成 BigInt 字面量。
BigInt support in TypeScript introduces a new primitive type called the bigint (all lowercase). You can get a bigint by calling the BigInt() function or by writing out a BigInt literal by adding an n to the end of any integer numeric literal:
在 TypeScript 中支持 BigInt,引入了一个新的称为 bigint (全部小写)的基本类型。你可以通过调用 BigInt() 函数或者通过直接在任意整数字面量的后面加上一个 n 来书写 BigInt 字面量而得到一个 bigint。
let foo: bigint = BigInt(100);// the BigInt function
let bar:bigint = 100n; // a BigInt literal
// Slaps roof of fibonacci function
// This bad boy returns ints that can getso big!
function fibonacci(n:bigint) {
let result = 1n;
for (let last = 0n, i = 0n; i < n; i++) {
const current = result;
result += last;
last = current;
}
return result;
}
fibonacci(10000n)
While you might imagine close interaction between number and bigint, the two are separate domains.
虽然你可能想要 number 和 bigint 之间紧密交互,但它们两个属于不同的领域。
declare let foo:number;
declare let bar:bigint;
foo = bar;// error: Type 'bigint' is not assignable to type 'number'.
bar = foo;// error: Type 'number' is not assignable to type 'bigint'.
As specified in ECMAScript, mixing numbers and bigints in arithmetic operations is an error. You’ll have to explicitly convert values to BigInts.
如在 ECMAScript 中规定的那样,在算术运算中混合 number 和 bigint 是错误的。你将必须显式地把值转换为 BigInt。
console.log(3.141592*10000n); //error
console.log(3145*10n); //error
console.log(BigInt(3145) *10n); //okay!
Also important to note is that bigints produce a new string when using the typeof operator: the string "bigint". Thus, TypeScript correctly narrows using typeof as you’d expect.
还需要关注的一点是,当对 BigInt 使用 typeof 运算符时将会产生一个新的字符串——“bigint”。因此,如你所期盼的那样,TypeScript 正确地收窄了 typeof。
function whatKindOfNumberIsIt(x:number | bigint) {
if(typeof x === "bigint") {
console.log("'x' is a bigint!");
}
else{
console.log("'x' is a floating-point number");
}
}
We’d like to extend a huge thanks to CalebSander for all the work on this feature. We’re grateful for the contribution, and we’re sure our users are too!
我们非常感谢 Caleb Sander 为这个特性所做的所有工作。我们很感谢这个贡献,我们也确信我们的用户也是如此!
Caveats
注意事项
As we mentioned, BigInt support is only available for the esnext target. It may not be obvious, but because BigInts have different behavior for mathematical operators like +, -, *,etc., providing functionality for older targets where the feature doesn’t exist (like es2017 and below) would involve rewriting each of these operations. TypeScript would need to dispatch to the correct behavior depending on the type, and so every addition, string concatenation,multiplication, etc. would involve a function call.
如我们所提到的,BigInt 的支持仅对 esnext 作为编译目标时可用。它可能不明显,但是因为BigInt 对于算术运行符如 +、-、 * 等有不同的行为,为那些不存在该特性的老版本目标(如 es2017 及以下版本)提供该功能将会涉及重写这每一个运算符。TypeScript 将需要依据类型调度正确的行为,所以每一个加法,字符串连接,乘法等,将会涉及到一个函数调用。
For that reason, we have no immediate plans to provide downleveling support. On the bright side, Node 11and newer versions of Chrome already support this feature, so you’ll be able touse BigInts there when targeting esnext.
鉴于此,我们没有立即计划提供降级的支持。可喜的是,Node 11 和更新版本的 Chrome 已经支持这个特性,所以当将编译目标设定为 esnext 时你将能够在这些平台使用 BigInt。
Certain targets may includea polyfill or BigInt-like runtime object. For those purposes you may want toadd esnext.bigint to the lib setting in your compiler options.
某些编译目标可能包含有兼容包(polyfill)或者类似 BigInt 的运行时对象。出于此目的你可能想要添加 esnext.bigint 到你的编译器选项的 lib设置中。
Object.defineProperty declarations in JavaScript
JavaScript 中的 Object.defineProperty 声明
When writing in JavaScriptfiles (using allowJs), TypeScript now recognizes declarations that use Object.defineProperty. This means you’ll get better completions, and stronger type-checking when enabling type-checking in JavaScript files (by turning on the checkJs option or adding a //@ts-check comment to the top of your file).
当编写 JavaScript 时(使用 allowJs 标志),TypeScript 现在能识别使用 Object.defineProperty 的声明了。这意味着你将得到更好的代码完成,以及当启用在JavaScript 中进行类型检查(通过打开 checkJs 选项或者在文件的顶部添加 //@ts-check 注释来开启)时更强的类型检查。
// @ts-check
let obj = {};
Object.defineProperty(obj,"x", { value:"hello", writable:false });
obj.x.toLowercase();
// ~~~
// error:
// Property 'toLowercase' does not exist on type 'string'.
// Did you mean 'toLowerCase'?
obj.x = "world";
// ~
// error:
// Cannot assign to 'x' because it is a read-only property.
Error message improvements
错误消息改进
We’re continuing to push improvements in the error experience inTypeScript. Here’s a few things in TypeScript 3.2 that we believe will make the language easier to use.
我们持续地推进 TypeScript 中的错误体验方面的改进。下面的这些是在 TypeScript 3.2 中我们相信将会使这个语言更易于使用。
• Better missing property errors (and cleaner missing attributes in JSX)
更好的属性缺失错误提示(以及 JSX 中的更简洁的特性缺失提示)
• Better error spans in arrays and arrow functions
数组和箭头函数中更好的错误提示(错误位置标示)
• Error on most-overlapping types in unions (a.k.a. “pick most overlappy type”)
联合类型中覆盖最广的类型的错误(又名“选取最广覆盖类型”)
TypeScript 3.2 之前的报错信息
TypeScript 3.2 的报错信息
• Related spans when a typed this is shadowed
当一个具有类型的 this 被隐蔽时的相对跨度提示
TypeScript 3.2 之前的报错信息
TypeScript 3.2 的报错信息
• “Did you forget a semicolon?” on parenthesized expressions on the next line
“你忘记了分号吗?”在下一行中的括号表达式上的提示
• More specific messages when assigning to const / readonly bindings
当赋值给 const / readonly 时更具体的信息
TypeScript 3.2 之前的报错信息
TypeScript 3.2 的报错信息
• More accurate message when extending complex types
扩展复杂类型时更精准的信息
TypeScript 3.2 之前的报错信息
TypeScript 3.2 的报错信息
• Use relative module names in error messages
在错误信息中使用相对模块名称
TypeScript 3.2 之前的报错信息
TypeScript 3.2 的报错信息
Thanks to Kingwl, a-tarasyuk, and prateekgoel who helped out on some of these improvements.
感谢 Kingwl、a-tarasyuk 和 prateekgoel 对这些改进所提供的帮助。
Improved narrowing for tagged unions
改进了的标记式联合类型的收窄
TypeScript 3.2 makes narrowing easier by relaxing rules for what’s considered a discriminant property. Common properties of unions are now considered discriminants as long as they contain some singleton type (e.g. a string literal, null, or undefined), and they contain no generics.
TypeScript 3.2 通过放宽判定什么是判别属性的规则使类型收窄变得更容易。联合类型的常规属性现在被认为是判别属性——只要它们包含某些孤立类型(如,字符串字面量,null 或 undefined)且不包含泛型。
As a result, TypeScript 3.2 considers the error property in the following example to be a discriminant, whereas before it wouldn’t since Error isn’t a singleton type. Thanks to this, narrowing works correctly in the body of the unwrap function.
结果,TypeScript 3.2 认为以下例子中的 error 属性是一个判别属性,而在此前的版本中则不是,因为 Error不是一个孤立类型。由于这点,unwrap 函数体中的收窄能够正确地工作。
type Either<T>=
| { error:Error; data:null}
| { error:null; data:T};
function unwrap<T>(result:Either<T>) {
if(result.error) {
// Here 'error' is non-null
throw result.error;
}
// Now 'data' is non-null
return result.data;
}
Editing improvements
编辑改进
The TypeScript project doesn’t simply consist of a compiler/type-checker. The core components of the compiler also provide a cross-platform open-source language service that can power “smarter” editor features like go-to-definition, find-all-references, and a number of quick fixes and refactorings. TypeScript 3.2 brings some small quality of life improvements.
TypeScript 项目不是简单的包含一个编译器/类型检查器而已。编译器的核心组件还提供了一个跨平台开源的语言服务,它能带来更“聪明”的编辑器特性,如转到定义,查找所有引用,以及许多快速修复和重构。TypeScript 3.2 为生活质量带来了一些小提升。
Quick fixes
快速修复
Implicit any suggestions and “inferfrom usage” fixes
修复隐式 any 建议和“从使用推导”
We strongly suggest users take advantage of stricter checking when possible. noImplicitAny is one of these stricter checking modes, and it helps ensure that your code is as fully typed as possible which also leads to a better editing experience.
我们强烈建议用户在可能的时候利用更严格的检查。noImplicitAny 是这些更严格的检查模式之一,且它能够帮助保证你的代码尽可能完全地类型化同时也能够带来更好的编辑体验。
Unfortunately it’s not all roses for existing codebases. noImplicitAny is a big switch across codebases which can lead to a lot of error messages and red squiggles in your editor as you type code. The experience can be jarring to turn on just to find out which variables need types.
不幸的是对于现有的代码库来说,这并不都是好的。noImplicitAny 是一个跨代码库的大开关,当你输入代码时,它会导致编辑器中出现大量的错误消息和红色波浪线。只是为了找出哪个变量需要类型,这种体验可能会让人震惊。
In this release, TypeScript produces suggestions for most variables and parameters that would have been reported as having implicit any types. When an editor reports these suggestions, TypeScript also provides a quick fix to automatically infer the types for you.
在这个版本中,TypeScript 为大多数变量和参数产生建议,这些变量和参数将被报告为具有隐式any 类型。当编辑器报告这些建议时,TypeScript也提供一个快速修复来为你自动推导这些类型。
This can make migrating an existing codebase to TypeScript even easier, and we expect it will make migrating to noImplicitAny a breeze.
这使得迁移现有代码库到 TypeScript 更容易,同时我们希望它能够使得迁移到noImplicitAny 变得轻而易举。
Going a step further,TypeScript users who are type-checking their .js files using checkJs or the // @ts-check comments can now also getthe same functionality with JSDoc types!
更进一步,通过使用 JSDoc类型,那些使用checkJs 或者 // @ts-check 注释来对他们的 .js文件进行类型检查的 TypeScript 用户现在同样可以得到相同的功能。
Other fixes
其它修复
TypeScript 3.2 also brings two smaller quick fixes for small mistakes.
TypeScript 3.2 同样为小错误带来了两个更小的快速修复。
• Add a missing new when accidentally calling a constructor.
当意外地调用了构造函数时添加一个缺失的new。
• Add an intermediate assertion to unknown when types are sufficiently unrelated.
当类型完全无关时添加一个中间断言到unknown。
Thanks to GitHub users iliashkolyar and ryanclarke respectively for these changes!
感谢 GitHub 用户 iliashkolyar 和 ryanclarke 分别为这些改变做的贡献。
Improved formatting
改进的格式化
Thanks to saschanaz,TypeScript is now smarter about formatting several different constructs. Listing all of them might be a bit cumbersome, but you can take a look at the pull request here.
感谢 saschanaz,TypeScript 现在对于格式化多个不同的结构更加的聪明了。列出所有的这些可能会有点繁重,但是你可以在这里查看拉取请求。
Breaking changes and deprecations
破坏性变更和弃用项
lib.d.ts changes
lib.d.ts 的变更
TypeScript has recently moved more to generating DOM declarations in lib.d.ts by leveraging IDL files provided by standards groups. Upgraders should note take note of any issues they encounter related to the DOM and report them.
TypeScript 最近通过利用标准组提供的 IDL 文件,已经在 lib.d.ts中生成更多的 DOM 声明。升级者应注意他们遇到的与DOM相关的任何问题并报告它们。
More specific types
更具体的类型
Certain parameters no longer accept null, or now accept more specific types as per the corresponding specifications that describe the DOM.
某些参数不再接受 null,或者按照那些描述 DOM的对应的规范现在接受更具体的类型。
More platform-specific deprecations
更多特定于平台的弃用项
Certain properties that are WebKit-specific have been deprecated. They are likely to be removed in a new version.
某些 WebKit 特定的属性已经被弃用。在新版本中它们很可能被移除。
wheelDelta and friends have been removed.
wheelDelta 及其关联项已经被移除
wheelDeltaX, wheelDelta, and wheelDeltaZ have all been removed as they are deprecated properties on WheelEvents.
wheelDeltaX、wheelDelta 和 wheelDeltaZ 都已被移除,因为它们是WheelEvent 上的弃用属性。
As a solution, you can use deltaX, deltaY, and deltaZ instead. If older runtimes are a concern, you can include a file called legacy.d.ts in your project and write the following in it:
你可以使用 deltaX、deltaY 和 deltaZ 来替代作为一个解决方案。如果要兼顾更旧版本的运行时,你可以在项目中包含一个叫 legacy.d.ts 的文件并在其中编写如下内容:
// legacy.d.ts
interface WheelEvent {
readonly wheelDelta:number;
readonly wheelDeltaX:number;
readonly wheelDeltaZ:number;
}
JSX resolution changes
JSX 解决方案的变更
Our logic for resolving JSX invocations has been unified with our logic for resolving function calls. While this has simplified the compiler codebase and improved some use-cases, there may be some differences which we may need to reconcile. These changes are likely unintentional so they are not breaking changes per se, but upgraders should note take note of any issues they encounter and report them.
我们用于解析 JSX 调用的逻辑已经统一为使用用于解析函数调用的逻辑。虽然这简化了编译器代码库并改进了一些用例,但是我们可能需要调解某些差异。这些变更可能是无意的,故它们本身没有破坏变更,但是升级者应注意他们遇到的任何问题并报告它们。
A note for NuGet and Visual Studio 2015
NuGet 和 Visual Studio 2015 要注意的一点
We have some changes comingin TypeScript 3.2 for NuGet and VS2015 users.
在 TypeScript 3.2 中我们为 NuGet 和 VS 2015的用户带来了一些变化。
First, TypeScript 3.2 and future releases will only ship an MSBuild package, and not a standalone compiler package. Second, while our NuGet packages previously shipped with the Chakra JavaScript engine to run the compiler, the MSBuild package now depends on an invokable version of Node.js to be present. While machines with newer versions of Visual Studio 2017 (versions 15.8 and above) will not be impacted, some testing / CI machines, users with Visual Studio 2015, and users of Visual Studio 2017 15.7 and below may need to install Node.js directly from the site, through Visual Studio 2017 Build Tools (read more here), or via a redistribution of Node.js over NuGet. Otherwise, upgrading toTypeScript 3.2 might result in a build error like the following:
首先,TypeScript 3.2 及将来的版本将只发布一个MSBuild 包而不是一个独立的编译器包。其次,虽然以前我们的 NuGet 包伴随着 Chakra JavaScript 引擎一起发布以运行编译器,但是MSBuild 包现在将以依赖于一个可调用的Node.js 版本的形式出现。虽然那些更新的版本的Visual Studio 2017(版本 15.8 及以上)的机器不会受影响,但是某些测试 / CI 机器、Visual Studio 2015 的用户以及 Visual Studio 2017 15.7 版本和更低版本的用户可能需要直接从站点安装 Node.js,通过 Visual Studio 2017 构建工具(了解更多),或者通过在 NuGet 上分发的Node.js 来安装。否则,更新到TypeScript 3.2可能会造成如下的构建错误:
The build task could not find node.exe which is required to run the TypeScript compiler. Please install Node and ensure that the system path contains its location.
构建任务无法找到 node.exe,它是运行 TypeScript编译器所必需的。请安装 Node 并确保系统环境变量中的“path”包含了它的位置。
Lastly, TypeScript 3.2 will be the last TypeScript release with editor support for Visual Studio 2015 users. To stay current with TypeScript, we recommend upgrading to Visual Studio 2017 for the latest editing experience.
最后,TypeScript 3.2 将会是支持 Visual Studio 2015 用户的最后一个 TypeScript 版本。为了保持与 TypeScript 版本一致,我们推荐升级到 Visual Studio 2017 以获得最新的编辑体验。
What’s next
下一步是什么
Our next release of TypeScript is slated for the end of January. Some things we’ve got planned on the horizon are partial type argument inference and a quick fix to scaffold out declaration files that don’t exist on DefinitelyTyped. While this list is influx, you can keep track of our plans on the TypeScript Roadmap.
我们的下一个 TypeScript 版本预计是在(2019 年)一月末。我们已经有了眉目的一些事情是:部分类型参数推断和快速修复以生成那些DefinitelyDyped 中不存在的声明文件。虽然这个列表在不断变化,但你可以在TypeScript 路线图上跟踪我们的计划。
We hope that TypeScript 3.2 makes your day-to-day coding more enjoyable, whether it comes to expressivity, productivity, or ease-of-use. If you’re enjoying it, drop us a line on Twitterat @typescriptlang; and if you’ve got ideas on what we should improve, file an issue on GitHub.
无论是表现力,生产力还是易用性,我们希望TypeScript 3.2 能让你的日常编程更开心。如果你喜欢它,请在 Twitter 上给 @typescriptlang 留言;如果你对我们应该作何改进有想法,请在 GitHub 上创建一个 issue 告知我们。
Happy hacking!
嗨起来吧!
– Daniel Rosenwasser and theTypeScript team
——Daniel Rosenwasser 和 TypeScript 团队
本文为公众号“TypeScript社区(QQ 群号 390037547)”原创翻译,转载请注明出处!否则追究法律责任!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。