五分钟了解 TypeScript

状态: 初稿

我们从用 TypeScript 构建一个简单的 Web 应用程序开始.

安装 TypeScript

主要有两种安装 TypeScript 的方式:

  • 通过 NPM(Node.js 包管理器)
  • 通过安装 Visual Studio 的 TypeScript 插件

Visual Studio 2017 和 Visual Studio 2015 Update 3 已经默认附带 TypeScript.
如果 TypeScript 没有随你的 Visual Studio 一起安装, 你可随时从此链接下载.

NPM 用户:

1
> npm install -g typescript

第一个 TypeScript 文件

打开你的编辑器, 键入以下内容, 并保存为 greeter.ts:

1
2
3
4
5
6
7
function greeter(person) {
return "Hello, " + person;
}

let user = "Jane User";

document.body.textContent = greeter(user);

编译 TypeScript 源程序

我们选用了 .ts 扩展名, 但其实那个程序只是 JavaScript.
与你在现有 JavaScript 应用中看到的没有区别.

打开命令行终端, 运行 TypeScript 编译器:

1
tsc greeter.ts

编译生成的文件是 greeter.js, 它的内容和输入的 .ts 文件并无二致.
我们在用 TypeScript 编译 JavaScript!

1
2
3
4
5
function greeter(person) {
return "Hello, " + person;
}
var user = "Jane User";
document.body.textContent = greeter(user);

来试试 TypeScript 带来的新东西吧.
在函数参数 person 后面添加 : string 类型注解, 就像这样:

1
2
3
4
5
6
7
function greeter(person: string) {
return "Hello, " + person;
}

let user = "Jane User";

document.body.textContent = greeter(user);

类型注解

TypeScript 借助类型注解来记录和约束变量, 函数的类型.
上例, 我们希望调用者传入一个 string 类型的参数 person 来调用被调函数 greeter.
我们尝试传入数组, 看看会发生什么:

1
2
3
4
5
6
7
function greeter(person: string) {
return "Hello, " + person;
}

let user = [0, 1, 2];

document.body.textContent = greeter(user);

重新编译, 你会看到一个错误:

1
error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

同样地, 试着移除 greeter 调用的所有参数.
总之, 如果传给函数的参数数量不对, TypeScript 会让你知道.
无论如何, TypeScript 都根据程序结构, 所有类型注解对程序执行静态分析.

注意编译器始终会创建 greeter.js, 而不管程序是否存在错误.
你可以编译包含错误的程序. 但 TypeScript 会提醒你程序可能不按你预期那样工作.

接口

在这一节, 我们创建一个名为 Person 的接口, 它这样描述一个类:拥有 firstName, lastName 两个成员变量.
在 TypeScript 中, 如果两个类型的内部结构(shape, 形体)是相容的, 它们自身也是相容的.
我们可以照接口要求的形体实现一个接口, 不需要显式 implements 子句.

1
2
3
4
5
6
7
8
9
10
11
12
interface Person {
firstName: string;
lastName: string;
}

function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

let user = { firstName: "Jane", lastName: "User" };

document.body.textContent = greeter(user);

TypeScript 同样支持 JavaScript 的新功能, 比如基于类的面向对象编程.
最后, 让我们为 Person 接口加入一个实现类.

该实现类名为 Student, 包含一个构造器和两个成员变量.
可以看到类和接口结合良好, 编程人员容易正确建立抽象层次.

注: public 修饰构造函数的参数自动在类中创建一个同名成员变量.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}

interface Person {
firstName: string;
lastName: string;
}

function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.textContent = greeter(user);

再次编译 greeter.ts, 你会看到 TypeScript 中的类模型被编译成了 JavaScript 常用的面向对象编程模式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Student = /** @class */ (function () {
function Student(firstName, middleInitial, lastName) {
this.firstName = firstName;
this.middleInitial = middleInitial;
this.lastName = lastName;
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
return Student;
}());
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "M.", "User");
document.body.textContent = greeter(user);

运行 TypeScript 应用

greeter.js 所在目录创建一个新 HTML 文件, 命名为 greeter.html, 键入以下内容:

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title></head>
<body>
<script src="greeter.js"></script>
</body>
</html>

现在, 你可以在浏览器中打开 greeter.html, 运行你第一个 TypeScript 应用!

注:用 Visual Studio 或 TypeScript playground 编辑 greeter.ts.
将鼠标指针悬停在标识符上, 就可以查看它们的类型信息.

greet_person.png

如果这篇文章对您有用,可以考虑打赏:)