〔译〕TypeScript 2.0 候选版发布

相关链接

TypeScript 2.0 正式版已经发布了:〔译〕TypeScript 2.0 正式版发布
不过可能大家更关心的是 〔译〕TypeScript 2.0 的新特性


原文:Announcing TypeScript 2.0 RC
August 30, 2016 by Daniel Rosenwasser

TypeScript 2.0 候选发行版(RC)出来了,离 TypeScript 2.0 最终发布也就不远了,赞!如果你还没开始使用 TypeScript,可以先看看网站上的教程

要使用 RC 版本,可以下载 TypeScript 2.0 RC for Visual Studio 2015(需要 VS2015 Update 3);也可以通过 NuGet 下载,或者像下面这样使用 npm:

npm install -g typescript@rc

Visual Studio Code 用户想使用 RC 版本请参考这里

这个 RC 版本让大家看到 2.0 正式版的样子,我们通过这个版本广泛收集用户反馈,将 2.0 打造得更加稳定可靠。总的来说,一般情况下 RC 版本已经足够稳定了,并且我们不希望再往上加新的特性。

不过,自 2.0 Beta 发布以来,已经加了不少东西,所以下面可能会有你尚未听说的新特性。

推断类型(Tagged Unions)

译者注

对于 Tagged Unions 的翻译,我查了很多资料,在 wiki 上找到如下描述:a tagged union, also called a variant, variant record, discriminated union, disjoint union, or sum type。其中 Variant 这个说法在 VB 中十分常用。在参考了 C# 对 var 关键字的翻译之后,我决定将其翻译为“推断类型”。

推断类型是一种数据结构,很像联合(C/C++程序员一定知道这个结构)。它有一个字段(或称为属性)用于识别当前结构的确切类型。(参考 What is a tagged union

推断类型使 JavaScript 在某些方向更像 F#、Swift 等语言。为此,JavaScript 程序员们一定会非常高兴。这个特性也叫 可识别联合互斥联合代理类型。不过特性本身显然比名称更有意思。

假设有两个类型:CircleSquare,然后定义它们的联合类型,命名为 Shape

interface Circle {
    kind: "circle";
    radius: number;
}

interface Square {
    kind: "square";
    sideLength: number;
}

type Shape = Circle | Square;

注意 CircleSquare 都有一个叫 kind 的字段,保存的字符串常数,表示类型。也就是说 Circlekind 总是 "circle"。每个类型都有一个共同的字段,但通过不同的值作为 标记 区分开来。

在 TypeScript 1.8 中,如果写一个获取面积的函数,需要判断 Shape 的每种类型。

function getArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            // 从 'Shape' 转换为 'Circle'
            let c = shape as Circle;
            return Math.PI * c.radius ** 2;

        case "square":
            // 从 'Shape' 转换为 'Square'
            let sq = shape as Square;
            return sq.sideLength ** 2;
    }
}

注意到我们为每种图形都使用了一个中间变量来使代码看起来简洁。

在 2.0 中就不再需要中间变量了。语言懂得如何通过 kind 来辨别类型,所以你可以少写点代码

function getArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            // 这里 'shape' 是 'Circle'
            return Math.PI * shape.radius ** 2;

        case "square":
            // 这里 'shape' 是 'Square'
            return shape.sideLength ** 2;
    }
}

上面的代码完全正确,TypeScript 能通过流程控制分析每个分支上的正确类型。可以使用 --noImplicitReturns 和即将可用的 --strictNullChecks 特性保证这些检查更彻底。

推断类型让 JavaScript 这种形式下的代码更简洁也更安全。例如,像 Redux 这样的库经常使用这种形式的来处理 action。每个独立的

更多字面类型

1.8 带来的字符串字面类型非常有用,就像上面看到的那样,可以用它来处理推断类型。

除了字符串,我们还想提供更多的类型。在 2.0 中,每个独特的布尔、数值或枚举成员都可以拥有自己的类型!

type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
let nums: Digit[] = [1, 2, 4, 8];

// 错误! '16' 不是 'Digit'!
nums.push(16);

这样在使用推断类型时,我们可以快速而地处理一些事情而毫无违和感。

interface Success<T> {
    success: true;
    value: T;
}

interface Failure {
    success: false;
    reason: string;
}

type Result<T> = Success<T> | Failure;

这里的 Result<T> 类型可能表示失败。如果表示成功,它有一个值,如果表示失败,它包含表示失败原因的 reson 字段。value 字段仅在 successtrue 的时候有效。

declare function tryGetNumUsers(): Result<number>;

let result = tryGetNumUsers();
if (result.success === true) {
    // 'result' 是 'Success<number>' 类型的
    console.log(`Server reported ${result.value} users`);
}
else {
    // 'result'是 'Failure' 类型的
    console.error("Error fetching number of users!", result.reason);
}

你可能已经注意到了,枚举值也可以拥有它们自己的类型!

enum ActionType { Append, Erase }

interface AppendAction { 
    type: ActionType.Append;
    text: string;
}

interface EraseAction {
    type: ActionType.Erase;
    numChars: number;
}

function updateText(currentText: string, action: AppendAction | EraseAction) {
    if (action.type === ActionType.Append) {
        // 'action' has type 'AppendAction'
        return currentText + action.text;
    }
    else {
        // 'action' has type 'EraseAction'
        return currentText.slice(0, -action.numChars);
    }
}

Globs语法、包含和排除

译者注

Globs 直译是“团块”的意思,不过这显然不如 Globs 本身意思明确。所以这里我没有翻译这个词。关于 Globs,可以参考 node-blog 在 README.md 中的说明。

首次向大家介绍 tsconfig.json 文件的时候,手工列出所有文件实在痛苦。TypeScript 1.6 引入了 excludes 配置来缓解这个问题;然而,这显然不够。痛苦在于,写完了每条文件路径,仍然会有问题发生,结果是因为忘了排除新文件。

TypeScript 2.0 终于开始支持 Globs 语法。Globs 允许我们在路径中使用通配符,这样一来,写路径再也不是件乏味的事了。

includeexclude 配置中都可以使用 Globs 语法。来看一个 tsconfig.json 的示例:

{
    "include": [
        "./src/**/*.ts"
    ],
    "exclude": [
        "./src/tests/**"
    ]
}

TypeScript globs 语法支持如下通配符:

  • * 匹配 0 个或多个字符,分隔符(比如 /\)除外
  • ? 精确匹配 1 个字符,分隔符除外
  • **/ 匹配任意层子目录

接下来的事

之前提到,TypeScript 2.0 很快就发布了,但是使用 RC 版本带来的 2.0 的新特性会为社区发展带来巨大的作用。

如果发现任何问题,可以 通过Github 反馈给我们。我们非常愿意听到你尝试之后给我们的反馈。祝愉快!


边城客栈
全栈技术专栏,公众号「边城客栈」,[链接]

一路从后端走来,终于走在了前端!

57.4k 声望
27.7k 粉丝
0 条评论
推荐阅读
树,计算父节点的值
前段时间回答了一个类似的问题,产生了写一篇博客的想法。这个问题确实存在一些常见的的应用场景,比如一个多层组织结构中,已知每个员工的绩效分,希望计算各级部门的绩效分以便对部门评优。

边城7阅读 524评论 2

封面图
正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青57阅读 8.7k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy49阅读 7.4k评论 12

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs42阅读 7k评论 12

封面图
「多图预警」完美实现一个@功能
一天产品大大向 boss 汇报完研发成果和产品业绩产出,若有所思的走出来,劲直向我走过来,嘴角微微上扬。产品大大:boss 对我们的研发成果挺满意的,balabala...(内心 OS:不听,讲重点)产品大大:咱们的客服 I...

wuwhs32阅读 3.6k评论 5

封面图
安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城29阅读 6.4k评论 5

封面图
2022大前端总结和2023就业分析
我在年前给掘金平台分享了《2022年热点技术盘点》的前端热点,算是系统性的梳理了一下我自己对前端一整年的总结。年后,在知乎上看到《前端的就业行情怎么样?》,下面都是各种唱衰前端的论调,什么裁员,外包化...

i5ting27阅读 2.4k评论 4

封面图

一路从后端走来,终于走在了前端!

57.4k 声望
27.7k 粉丝
宣传栏