【译】TypeScript 2.2 候选版发布

TypeScript 2.2即将到来,今天我们发布候选版!

如果你是第一次听说TypeScript,那不要紧的,因为TypeScript是一门在JavaScript的基础上添加可选静态类型的语言。基于JavaScript构建,意味着你不需要学习JavaScript以外太多的知识,并且所有现有的代码你也可以使用TypeScript。同时,TypeScript添加的可选类型可以帮助您捕获讨厌的bug,还有通过启用强大的工具支持能提高工作效率。

今天就试试候选版本,你可以使用NuGet获取,或者使用npm运行

npm install -g typescript@rc

您还可以获取Visual Studio 2015的TypeScript版本候选版本(如果已经安装了Update 3)。对其它编辑器的支持得等到我们正式的2.2版本,但你可以看看在Visual Studio CodeSublime Text 3中如何启用更高版本的TypeScript的指南。

为了告诉你新增了哪些特性,这里有几个值得注意的特性来了解此候选版本。

object类型

有些时候,一个API允许你传递除基本类型外任何类型的值。例如,思考Object.create,除非你传递一个对象或null给第一个参数,否则它抛出一个异常。

// 所有这些在运行时都会抛出错误!
Object.create(undefined);
Object.create(1000);
Object.create("hello world");

如果我们试图想出第一个参数的类型,一个简单的方法可能是Object | null。不幸的是,这并不完全奏效。由于结构类型在TypeScript中工作的方式,numberstringboolean都属于Object

为了解决这个问题,我们创建了新的object类型(注意所有这些字母都是小写的!)。
一个更直白的名称可以叫“非基本”类型。

object类型是“空” – 它没有属性,就像{}类型。
这意味着几乎一切都可以分配给object,除了基本类型外。
换句话说,将与numberbooleanstringsymbolnullundefined类型不兼容。

但这意味着我们现在可以正确地将Object.create的第一个参数类型作为object | null

我们预期object基本类型将帮助捕获一大类bug,并更准确地模拟真实世界规范。

我们非常感谢Herrington Darkholme的援手实现这个特性!

改进了对mixins和组合类的支持

mixin模式在JavaScript生态系统中相当常见,在TypeScript 2.2中,我们对语言进行了一些调整,以更好地支持它。

为了做到这一点,我们在TypeScript 2.2中删除了对类的一些限制,就像能够从构造交集类型的值中扩展一样。它还以交集类型上的签名组合的方式调整一些功能。结果是你可以写一个函数

  1. 接受构造函数
  2. 声明一个继承该构造函数的类
  3. 向该新类添加成员
  4. 并返回类本身。

例如,我们可以编写接受一个类的Timestamped函数,并通过添加一个timestamp成员来扩展它。

/** Any type that can construct *something*. */
export type Constructable = new (...args: any[]) => object;

export function Timestamped<BC extends Constructable>(Base: BC) {
 return class extends Base {
 timestamp = new Date();
 };
}

现在我们可以使用任何类通过Timestamped,快速组成一个新的类型。

class Point {
 x: number;
 y: number;
 constructor(x: number, y: number) {
 this.x = x;
 this.y = y;
 }
}

const TimestampedPoint = Timestamped(Point);

const p = new TimestampedPoint(10, 10);
p.x + p.y;
p.timestamp.getMilliseconds();

类似地,我们可以写一个Tagged函数来添加一个tag成员。这些函数实际上使得很容易组合扩展。制作一个带有标签和时间戳的特殊3D点是相当干净的。

class SpecialPoint extends Tagged(Timestamped(Point)) {
 z: number;
 constructor(x: number, y: number, z: number) {
 super(x, y);
 this.z = z;
 }
}

新的JSX生成模式:react-native

在TypeScript 2.1和更早版本中,--jsx编译参数可以使用两个值:

  • preserve 保留JSX语法,并生成.jsx文件。
  • react 将JSX转换为对React.createElement的调用并生成.js文件。

TypeScript 2.2有一个新的JSX生成模式称为react-native,它处于中间位置。在这个方案下,保留JSX语法,但生成.js文件。

这个新模式包含React Native的加载器,它希望所有输入的文件都是.js文件。它既能满足你保留JSX语法又可以从TypeScript获取.js文件的情况。

下一步

我们无法在本篇博客中列出我们工作的一切,你可以在TypeScript Roadmap中看看还有哪些特性。

我们期望您的反馈帮助TypeScript 2.2固定版本的发布!
如果你遇到任何可能的bug,请随时在这里留下反馈,或在GitHub上提出问题

1.学习TypeScript——使用VS Code搭建TypeScript开发环境

前言

TypeScript和VSCode已经成为了2016年前端开发最流行的开发语言和开发工具之一,更多请看2016年JavaScript流行详情。使用TypeScript语言开发的类库和框架也越来越多,鼎鼎大名的Google的Angular 2中文网)项目就是使用TypeScript作为主要的开发语言的(还有JS版本和Dart版本)。

现在浏览器显然已经不能满足了JS了,很多App也开始使用JS开发了,使用基于TypeScript的IonicNativeScript能够快速高效地帮助你开发APP。

TypeScript是JavaScript的超集,TypeScript只是增强了JavaScript而非改变了JavaScript,TypeScript同样也是基于ECMAScript标准的编程语言。因此非常流行的Vue和React及我们常用Jquery等类库都可以使用TypeScript来编码,TypeScript强大的智能类型分析系统,能够使你的代码更加强壮。

说了这么多TypeScript的优点,下面让我们来学习如果在VScode中使用TypeScript开发项目吧。

下载TypeScript

TypeScript官网中文网)提供了多种下载方式,我们使用NPM来下载TypeScript,如果你没有安装NPM,请到Nodejs官网进行安装。

在CMD(Windows系统)或者终端(macOS系统)中输入一下命令:

npm install -g typescript

安装完毕后我们输入tsc -v可以查看当前安装的TypeScript版本号。当前最新的版本是2.1.5。

下载VSCode

VSCode是我使用过最棒的编辑器没有之一,比Sublime Text还有优秀。

VSCode官网就可以下载相应系统的VSCode安装包,最新的VSCode版本是1.9。

VSCode下载图

创建项目

创建目录

首先我们创建一个项目文件夹,比如叫ts_vscode,然后创建一些主要目录,在VSCode中打开项目,在macOS上我们可以直接使用命令来操作:

# 创建ts_vscode及主要文件夹
mkdir -p ts_vscode/src/{css,images,fonts}

# 使用VSCode打开
code ts_vscode

目录结构:

ts_vscode/
    └─src/
        ├─ css/
        ├─ fonts/
        └─ images/

创建package.json

使用命令npm init来创建package.json文件,一般默认就可以,具体详情可以看这里

创建

目录结构:

ts_vscode/
    ├─ src/
    │    ├─ css/
    │    ├─ fonts/
    │    └─ images/
    └─ package.json

创建tsconfig.json

使用tsc --init命令就可以快速创建一个tsconfig.json文件,关于tsconfig.json的属性描述请访问这里

目录结构:

ts_vscode/
    ├─ src/
    │    ├─ css/
    │    ├─ fonts/
    │    └─ images/
    ├─ package.json
    └─ tsconfig.json

安装项目依赖和开发依赖

我们的这个项目使用jQuery和Bootstrap来做,因此我们使用npm来安装:

npm install jquery bootstrap --save

我们的项目使用了TypeScript来开发,因此我们需要下载相对应的声明文件,关于声明文件请访问这里。安装声明文件命令:

npm install @types/jquery @types/bootstrap -save-dev

创建index.html

ts_vscode目录下创建index.htmlindex.html文件中放入下面的代码:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>TypeScript with VSCode</title>
  <!-- Bootstrap -->
  <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css">
  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
  <![endif]-->
  <link rel="stylesheet" href="./src/css/index.css">
</head>

<body>
  <h1 class="text-center"></h1>
  <div class="container">
    <div class="row show-grid">
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
      <div class="col-md-1">.col-md-1</div>
    </div>
    <div class="row show-grid">
      <div class="col-md-8">.col-md-8</div>
      <div class="col-md-4">.col-md-4</div>
    </div>
    <div class="row show-grid">
      <div class="col-md-4">.col-md-4</div>
      <div class="col-md-4">.col-md-4</div>
      <div class="col-md-4">.col-md-4</div>
    </div>
    <div class="row show-grid">
      <div class="col-md-6">
        <button type="button" class="btn btn-default" aria-label="Left Align">
          <span class="glyphicon glyphicon-align-left" aria-hidden="true"></span>
        </button>
      </div>
      <div class="col-md-6">
        <button type="button" class="btn btn-default btn-lg">
          <span class="glyphicon glyphicon-star" aria-hidden="true"></span> Star
        </button>
      </div>
    </div>
  </div>
  <!-- /.modal -->
  <!-- js -->
  <script src="./node_modules/jquery/dist/jquery.min.js"></script>
  <script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
  <script src="./src/index.js"></script>
</body>

</html>

目录结构:

ts_vscode/
    ├─ src/
    │    ├─ css/
    │    ├─ fonts/
    │    └─ images/
    ├─ index.html
    ├─ package.json
    └─ tsconfig.json

创建index.ts文件并编写TS代码

src目录下创建index.ts文件。我们使用TS编写一个类,并使用这个类的方法向index.htmlh1标签中插入一句话,代码如下:

class Main {
    constructor() {

    }

    name: string;

    show(text: string): void {
        let $ele: JQuery = $("h1");
        $ele.text(text);
    }
}

let main = new Main();
main.name = "Hello TypeScript";
main.show(main.name);

目录结构:

ts_vscode/
    ├─ src/
    │    ├─ css/
    │    ├─ fonts/
    │    ├─ images/
    │    └─ index.ts
    ├─ index.html
    ├─ package.json
    └─ tsconfig.json

编译和启动项目

我们使用package.json中的scripts来编译和启动项目。

编译比较简单,tsc命令就可以编译项目,tsc -w命令监控并自动编译,编译会使用tsconfig.json中的配置项。

启动项目我们安装live-server,来帮助我们启动一个服务器环境,live-server非常轻便且带有自动刷新功能,我们使用npm全局安装即可:

npm install -g live-server

安装完毕后,我们修改package.json中的scripts如下:

"scripts": {
    "test": "tsc -w & live-server"
}

最终目录结构:

最终目录结构

最后我们在终端中输入npm t就可以启动项目了,启动成功后如下图:

启动项目成功

尝试改变项目文件,你可以发现浏览器会自动编译和自动刷新哦。

总结

本文章我们认识了VSCode和TypeScript,学会了基本的安装和编译及简单的TypeScript代码编写。本篇文章的示例代码请访这里

下篇文章我们将学习如何构建打包TypeScript项目。

[译]TypeScript 2.1 候选版:更好的类型推断、异步函数和其它更多特性

今天我们非常高兴地宣布发布TypeScript 2.1 候选版!如果您不熟悉它,TypeScriptTypeScript中文网)是一种向JavaScript添加可选静态类型的语言,并将来自ES6和更高版本的新特性带到您使用的任何JavaScript运行时。

像往常一样,你可以通过NuGet得到RC,或仅通过运行

npm install -g typescript@rc

然后,您可以轻松地在Visual Studio Code我们的Sublime Text插件中使用RC版本。

在VS2015上安装Update 3后,就可以下载Visual Studio 2015的TypeScript 2.1安装包

虽然TypeScript 2.1有很多很棒的功能,但我们想要强调的是,TypeScript 2.1的类型推断功能将会更强大,以及更容易在所有运行时编写异步代码。

更加智能的类型推断

TypeScript 2.1现在可以更容易地模拟逐渐初始化变量的场景。由于很多代码在JavaScript中是这样写的,这使得将现有的代码库迁移到TypeScript变得更加容易。

为了更好地理解,让我们先谈谈any类型。

大部分的时间,如果TypeScript不能找出一个变量的类型,它会选择尽可能灵活不困扰你的any类型。我们经常称之为隐式any类型(而不是一个明确的你会写出来的类型)。

let x;      // 隐式 'any'
let y = []; // 隐式 'any[]'

let z: any; // 显式 'any'.

从这一点上,你可以使用这些值做任何你想要做的事情。对许多人来说,这种行为太松散了,这就是为什么--noImplicitAny编译参数会在无法推断类型时发出警告。

在TypeScript 2.0中,我们构建了使用控制流分析来跟踪整个程序中类型流的基础。因为该分析检查每个变量的赋值,我们在TypeScript 2.1中利用了同样的基础,更深入地检查了每一个变量的类型,它看起来像是一个更好的类型。而不是只是选择any,TypeScript将根据你最终的赋值来推断类型。

让我们来看下面的例子。

let x;

// 我们仍然可以给'x'赋任何我们需要的值。
x = () => 42;

// 在刚才赋值后,TypeScript 2.1 知道'x'的类型是'() => number',
// 因此它可以被调用。
x();

// 但现在我们会得到一个错误,我们不能添加一个数字到函数!
console.log(x + 42);
//          ~~~~~~
// 错误!运算符 '+' 不能应用于类型`() => number`和'number'。

// TypeScript仍然允许你给'x'赋值你需要的任何值。
x = "Hello world!";

// 但现在它仍然知道'x'是'string'类型的!
x.toLowerCase();

当涉及到赋值,TypeScript仍然会相信你,并允许你给x赋值任何你需要的值。然而,对于任何其他的用途,the type checker will know better by climbing up and looking at whatever you’ve actually done with x.

现在对空数组也进行同样的跟踪。这意味着更好的完成:

let puppies = [];

puppies.push(new Puppy());

for (let pup of puppies) {
    pup.bark();
    //  ^^^^ Get completion on 'bark'
}

这也意味着TypeScript可以捕获更多的明显的错误:

puppies[1] = new Kitty();

for (let pup of puppies) {
    pup.bark();
    //  ~~~~ 错误:'bark'不存在'Kitty'类型中
}

所有这一切的最终结果是,将来你会看到较少隐式any错误,并得到更好的工具支持。

低版本异步函数

TypeScript 2.1将支持低版本异步函数(即async/await),并且现在你就可以在候选版本中使用它!async/await是ECMAScript 2017版本中的新特性,它允许用户在promise中编写代码,而不需要使用回调。async函数写出来的代码风格看起来像同步代码那样,但使用await关键字异步运行。

该特性在TypeScript 2.1之前就已经支持了,但是只能编译为ES6或者ES2015。TypeScript 2.1使其该特性可以在ES3和ES5运行时上使用,这意味着无论您使用什么环境,都可以使用它。

例如,让我们使用下面名为delay的函数,它返回一个promise并在完成之前等待一定的时间:

function delay(milliseconds: number) {
    return new Promise<void>(resolve => {
      setTimeout(resolve, milliseconds);
    });
}

让我们尝试一个简单的探索任务。我们要写一个程序,打印"Hello",三个点,接着是"World!"

function welcome() {
    console.log("Hello");

    for (let i = 0; i < 3; i++) {
        console.log(".");
    }

    console.log("World!");
}

原来是听起来很简单。

现在让我们假设我们要使用我们的delay函数在每个点之前暂停。

没有async / await,我们必须写如下:

function dramaticWelcome() {
    console.log("Hello");

    (function loop(i){
        if (i < 3) {
            delay(500).then(() => {
                console.log(".");
                loop(i + 1);
            });
        }
        else {
            console.log("World!");
        }
    })(0);
}

这看起来不那么简单了!如果我们尝试使用async函数来使这个代码更具可读性呢?

首先,我们需要确保我们的运行时具有全局可用的符合ECMAScript的Promise。这可能需要获取Promise的polyfill,或依赖于你指定版本运行时中其中的一个。我们还需要确保TypeScript知道Promise存在,通过将我们的lib编译参数设置为像“dom”,“es2015”或“dom”,“es2015.promise”,“es5”:

{
    "compilerOptions": {
        "lib": ["dom", "es2015.promise", "es5"]
    }
}

现在我们可以使用asyncawait来重写代码:

async function dramaticWelcome() {
    console.log("Hello");

    for (let i = 0; i < 3; i++) {
        await delay(500);
        console.log(".");
    }

    console.log("World!");
}

请注意,与我们的同步版本的代码相比,这是多么相似!尽管它看起来像同步的,但这个函数实际上是异步的,并且不会阻止其他代码在每次暂停之间运行。事实上,dramaticWelcome的两个版本从基本上归结为相同的代码,但是使用async&await,TypeScript为我们提供了很大的帮助。

下一步

TypeScript 2.1 RC有很多其他特性,我们将有更多的适用于2.1。你可以看看我们的路线图,看看在存储区还有哪些特性。我们希望你尝试一下并且享受它!