
如果您不熟悉TypeScript,那么它是一种将静态类型检查引入JavaScript的语言,因此您甚至可以在运行代码之前甚至保存文件之前就发现问题。 它还将旧版浏览器和运行时中的ECMAScript标准编译为它们可以理解的形式,从而包括ECMAScript标准提供的最新JavaScript功能。 但是除了类型检查和编译代码之外,TypeScript还可以在您喜欢的编辑器中提供工具,以便您可以跳转到任何变量的定义,查找谁在使用给定功能,并自动进行重构和修复常见问题。
原始博客TypeScript甚至为JavaScript用户提供了此功能(并且还可以对使用JSDoc输入的JavaScript代码进行类型检查),因此,如果您在.js
文件上使用了Visual Studio或Visual Studio Code之类的编辑器,TypeScript将为您带来这种体验。
要开始使用TypeScript,可以使用以下命令通过NuGet或npm获得它:
npm install -g typescript
您还可以通过以下方式获得编辑器支持
TypeScript 3.3是一个比平常小的版本,并且没有重大更改,因此,如果您使用的是旧版本,则应该易于升级。 让我们探索3.3的新功能!
改进了调用联合类型的行为
当TypeScript具有联合类型A | B
A | B
,它允许您访问A
和B
都共有的所有属性(即成员的交集)。
interface A { aProp: string; commonProp: string; } interface B { bProp: number; commonProp: number } type Union = A | B; declare let x: Union; x.aProp;
这种行为应该感觉很直观-如果已知每种类型的联合类型,则只能从联合类型中获取属性。
那不是访问属性,而是处理调用类型呢? 好吧,当每种类型都只有一个带有相同参数的签名时,事情就起作用了,您可以调用这些类型。
type CallableA = (x: boolean) => string; type CallableB = (x: boolean) => number; type CallableUnion = CallableA | CallableB; declare let f: CallableUnion; let x = f(true);
但是,有时这种限制过于严格。
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;
除了愚蠢的示例和较差的错误消息外, FruitEater
和ColorConsumer
都应能够使用字符串"orange"
,并返回number
或string
。
在TypeScript 3.3中,这不再是错误。
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;
在TypeScript 3.3中,这些签名的参数相交在一起以创建新的签名。 在上面的示例中,参数fruit
和color
相交在一起,成为了Fruit & Color
类型的新参数。 Fruit & Color
实际上与("apple" | "orange") & ("red" | "orange")
,等同于("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
。 每个不可能的交集都消失了,剩下的只是"orange"
。
但是仍然有一些限制。 仅当联合体中最多一种类型具有多个重载并且联合体中最多一种类型具有通用签名时,才会启动此新行为。 这意味着对number[] | string[]
像map
一样的number[] | string[]
(通用)仍然无法调用。
另一方面,诸如forEach
方法现在可以调用,但是在noImplicitAny
下可能存在一些问题。
interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach(animal => {
尽管我们将继续改善此处的体验,但在TypeScript 3.3中,它的功能更加强大,并且可以添加显式类型注释。
interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach((animal: Dog | Cat) => { if (animal.kind === "pupper") { animal.dogProp;
--build --watch
复合项目的增量文件监视
在TypeScript 3.0中,我们引入了一种用于构建构建的新功能,称为“复合项目”。 目标的一部分是确保用户可以将大型项目分解为较小的部分,以快速构建并保留项目结构,而不会损害现有的TypeScript体验。 多亏了复合项目,TypeScript可以使用--build
模式仅重新编译项目集和依赖项。 您可以将其视为优化项目间构建。
但是,大约在去年左右,我们的团队还通过新的增量“构建器” API交付了优化的--watch
模式构建。 同样,整个想法是,此模式仅重新检查并重新发出更改的文件或依赖关系可能影响类型检查的文件。 您可以将其视为优化项目内部构建。
具有讽刺意味的是,使用--build --watch
构建复合项目实际上并未使用此基础结构。 在--build --watch
模式下在一个项目中进行更新将强制该项目的完整构建,而不是确定该项目中的哪些文件受到了影响。
在TypeScript 3.3中,-- --watch
模式的--watch
标志也确实利用了增量文件监视。 这可能意味着--build --watch
下的构建速度显着提高。 在我们的测试中,此功能使原始--build --watch
时间的构建时间减少了50%至75% 。 您可以阅读有关原始变更请求的更多信息,以查看具体数字,但我们相信大多数复合项目用户将在这里看到巨大的成功。
Sublime Text中的JavaScript编辑
感谢前TypeScript团队成员Zhengzhenbo Li和社区贡献者@idiotWu所做的工作 ,我们用于Sublime Text的TypeScript插件现在支持在JavaScript文件中进行编辑! 这意味着用户将利用JSDoc并与TypeScript代码进行互操作,从而获得更准确的补全,重命名,定义以及更多的JavaScript代码。

接下来是什么?
如果您错过了它,TypeScript项目最近发布了我们为期6个月的路线图 ,概述了我们希望在一月至六月之间完成的工作。 要跟踪TypeScript 3.4中的后续功能并进行跟踪,可以关注我们的功能路线图页面 。
我们希望TypeScript 3.3继续提高您的工作效率,并使您在编写代码时更加快乐。 如果您喜欢它,请在Twitter上告诉我们,如果您对我们可以改进的地方有任何建议,请在GitHub上提交问题 。
骇客入侵!
-Daniel Rosenwasser和TypeScript团队