TypeScript初体验

  • 万年不变的开头,TypeScript 慢慢学习之路

1. 什么是Typescript?

说到 TypeScript 一定离不开我们非常熟悉的 JavaScript,先单纯从名字上看TypeScript,再看 ‘TypeScript’ - ‘type script’ - ‘type’,有没有发现type这个词很有意思,也就是”类型”的意思,TypeScript这样的命名也意味着 ts 是离不开”类型”这个词的,正如官网定义:

Typed JavaScript at Any Scale.
添加了类型系统的 JavaScript,适用于任何规模的项目。

这也带出了 TypeScript 的两个最重要的特性 —— 类型系统、适用于任何规模

2. Javascript和Typescripy的区别

在类型系统的分类上看:

  • 类型系统 按照「类型检查的时机」来分类,可以分为动态类型和静态类型。

JavaScript 是一门解释型语言,没有编译阶段,它就是一种动态类型,所以在代码运行时才会报错

而静态类型是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。TypeScript 在运行前需要先编译为 JavaScript,而在编译阶段就会进行类型检查,所以 TypeScript 是静态类型的

  • 类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型:
1
2
console.log(1 + '1');
// 打印出字符串 '11'

上面这段代码,用过js的小伙伴肯定都知道发生隐式类型转换之后,1 + ‘1’ 会变成 ‘11’,所以 js 是弱类型的。反看 TypeScript 它是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性,所以这段代码在 ts 中运行结果也是 ‘11’,所以 TypeScript 也是弱类型

而TypeScript 不同于 JavaScript ,ts是支持强类型和静态类型的,也被称为 JavaScript 超集,它支持ES6语法,包含了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法,支持面向对象编程的概念,如类、接口、继承、泛型等。

接下来总结一下js 和 ts 区别:

  • TypeScript 并不直接在浏览器上运行,而是需要编译器编译成纯 JavaScript 来运行。
  • TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。
  • TypeScript 代码可以在无需任何修改的情况下与 JavaScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。
  • TypeScript 通过类型注解提供编译时的静态类型检查。
  • TypeScript 中的数据要求带有明确的类型,JavaScript 不要求。
  • TypeScript 为函数提供了缺省参数值。
  • TypeScript 引入了 JavaScript 中没有的“类”概念。
  • TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。

下面通过表格更明显的来对比一下:

TypeScript JavaScript
后缀名 .ts 后缀名 .js
支持ES6 不支持ES6
支持强类型和静态类型 不支持强类型和静态类型
编译时报错 运行时报错
支持面向对象编程概率,如接口、继承、类、泛型等 是一种脚本语言
支持模块 不支持模块
支持泛型 不支持泛型
不支持在浏览器端运行,需要编译成js 支持在浏览器端运行

3. 环境搭建

了解了大概什么是ts之后,下面就实际操作试一下

因为 TypeScript 需要编译为 JavaScript 才能运行,所以需要Node环境的支持,在编译前请保证你本地已经安装 Node 运行环境

有两种主要的方式来获取TypeScript工具:

  • 通过npm(Node.js包管理器)
1
2
3
npm install typescript -g
# OR
yarn global add typescript
  • 安装Visual Studio的TypeScript插件

查看TypeScript版本:

1
tsc --version

4. TypeScript 初体验

安装了ts之后来初体验一下,构建你的第一个ts文件:

在一个目录下,利用 touch 命令创建一个ts文件

1
touch demo.ts

然后将下面这段代码,复制进去,聪明的你一定看出来这不就是 js 嘛,对的,就是 js 代码,现在只是想让你初体验一下 ts 编译

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

const user = "Jane User";

document.body.innerHTML = greeter(user);

编译代码,在命令行上,运行TypeScript编译器:

1
tsc greeter.ts

输出结果为一个 greeter.js 文件,内容和我们之前输入的一样(因为原来就是 js 编写的),现在我们就利用 ts 改写一下

我们利用 ts 提供的 类型注解(是一种轻量级的为函数或变量添加约束的方式) 来给 person 函数的参数添加: string 类型注解,如下:

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

const user = "Jane User"

document.body.innerHTML = greeter(user)

这意味着 greeter 函数的 person 参数只能接收 string 类型的参数,而且是必传参数,如果传入其他类型或者不传参数就会报错,如果想要改为可选参数,冒号前添加一个问号,则表明该参数是可选的,所以可以写成这样:

1
2
3
function greeter(person?: string) {
return "Hello, " + person
}

要注意的是尽管有错误,greeter.js 文件还是被创建了。 就算你的代码里有错误,你仍然可以使用 TypeScript。但在这种情况下,TypeScript会警告你代码可能不会按预期执行

有小伙伴可能会问,如果我要传入的参数不是一个基本数据类型,如果是一个对象怎么办?

这就要用到 ts 的另一个概念 - 接口(接口是一系列抽象方法的声明,是一些方法特征的集合):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 使用接口来描述一个拥有 firstName 和 lastName 字段的对象

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

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

// 赋值的时候,变量的形状必须和接口的形状保持一致

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

document.body.innerHTML = greeter(user);

interface 是仅存在于TS上下文中的一种虚拟结构,TS编译器依赖接口用于类型检查,最终编译为JS后,接口将会被移除,它只是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)

与其他语言相比,JS并没有直接对类的描述,只有基于原型的继承方式,一直到了ES6,class 关键字作为一种语法糖出现,而 TypeScript 是面向对象的 JavaScript,也就支持面向对象的所有特性,比如 类、接口等

TypeScript 类定义方式如下:

1
2
3
class class_name { 
// 类作用域
}

与 interface 不同,class 作为TS的一种变量类型存在于上下文之中,class 中可以提供,变量、方法等的具体实现方式等,它的作用不仅仅是约束数据结构

最后,让我们使用类来改写这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 注意类和接口可以一起共作,我们可以自行决定抽象的级别

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

class Student {
fullName: string;
// 在构造函数的参数上使用public等同于创建了同名的成员变量
constructor(public firstName, public middleInitial, public lastName) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}

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

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

document.body.innerHTML = greeter(user);

接下来我们来实际运行一下:

使用命令 mkdir 在终端创建一个 demo 文件夹

1
mkdir demo

cd 到 demo 文件目录下:

1
cd demo

然后利用命令 touch 在终端创建一个 greeter.ts 文件以及一个 index.html 文件

1
2
3
touch greeter.ts

touch index.html

这样我们就在 demo 文件目录下,创建了两个文件,分别是 greeter.ts 和 index.html

将我们刚才的代码复制到 greeter.ts 文件中

要想 greeter.ts 运行起来,我们需要先编译 ts 文件为 js 文件,然后通过 html 文件引用,在浏览器端运行

利用 tsc 编译 ts 文件为 js 文件

1
tsc greeter.ts

编译完成,我们会在 demo 文件目录下发现 多了一个 greeter.js 文件,然后我们在 html 文件中引用

编译后的 greeter.js 文件:

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.innerHTML = greeter(user);

index.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>

然后我们将 html 文件用浏览器打开,看到页面出现 “Hello, Jane User”

Comentarios

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×