
今天,我们很高兴宣布TypeScript 3.3的候选发布(RC)可用。 我们希望收集反馈和早期问题,以确保最终版本易于获取和使用。
原始博客要开始使用RC,可以通过NuGet或通过以下命令使用npm来进行使用:
npm install -g typescript@rc
您还可以通过以下方式获得编辑器支持
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% 。 您可以阅读有关原始变更请求的更多信息,以查看具体数字,但我们相信大多数复合项目用户将在这里看到巨大的成功。
接下来是什么?
在3.3以外的版本中,您可以随时关注我们的路线图页面 。
但是现在,我们期待听到您在RC方面的经验,因此请立即尝试一下,让我们知道您的想法!
-Daniel Rosenwasser和TypeScript团队