0%

TypeScript入门

TypeScript
我们要学习一门新知识,首先要了解一些新知识的历史。TypeScript 是微软开发的,它的出现是为了解决 JavaScript 没有类型检查的弊端。因此,TypeScript并不是一门新语言,它的作用就是帮JavaScript检查数据类型是否正确,所以称它为JavaScript的一个超集是更贴切的。

有很多同学对 TypeScript 产生疑惑,他们会问 TypeScript 可以在浏览器上运行吗?

虽然TypeScriptJavaScript的一个超集,但由于它要进行类型检查,所以就与 JavaScript 的语法有一些不同了,因此 TypeScript 编写的程序是无法直接运行在浏览器上的。

TypeScript 工作原理

在讲解 TypeScript 工作原理之前,有一句话是你必须清楚且要印在脑子里的: 在浏览器上,只能运行 JavaScript 脚本

既然浏览器里只能运行JavaScript,那TypeScript具体又做了什么事儿呢?下面我就向你解释一下TypeScript都做了哪些事儿。

学习过编译原理的同学都清楚,类型检查就是语法分析,它属于编译器的范筹。TypeScript官网说: “TypeScrpt是JavaScript的超集,可以进行JavaScript类型检查。” 表明TypeScriptJavaScript增加了类型语法,并且它还有一个编译器,可以将用TypeScript语法编写的程序(.ts文件),翻译成 JavaScript 脚本语言。

因此,TypeScript的使用步骤一定是这样的: 首先用 TypeScript 语法编写程序;然后编译,输出JavaScript脚本;最终在浏览器中引用生成的 JavaScript 脚本这样一个过程。

实际情况也确实如此,在TypeScript的官网上你可以找到,TypeScript 有一个编译工具称为 tsc,即 t(ype) s(cript) c(ompiler)的缩写 。

JavaScript的最大问题

使用过其它面向对象语言的同学们再使用JavaScript开发时,都会觉得特别难受,因为JavaScript无法进行类型检查。对于Javascript语法来说,你传给它什么类型的数据都可以,这样虽然看似很很好,但一旦你将数据传错了,你得到的结果就是错误的。当错误出现时,没有任何的提示,光凭我们肉眼去查找错误实在是太费力了,这就是JavaScript的最大问题。

我们来看一个最简单的JavaScript例子你应该就清楚了:

1
2
3
function func(msg){
console.log("the message is :" + msg);
}

上面这段代码是一段最简单的JS代码,它需要一个字符串参数。但由于JavaScript并没有对参数的类型做限制,所以你在调用这个函数时,可以给他传任意的值。如下:

1
2
3
func(123);
func('this is my book!');
func(func);

我的本意是只有第二种调用func的方式才是正确的,但在JavaScript中上面这几种调用func函数的方法都是正确的。在我们实际工作中,我们写了很长的代码后,传入了一个错误的值时JavaScript就无法为我们检测出那里出错了,这是最可怕的。

这也是为什么TypeScript逐渐受到大家喜欢的原因。

一个最简单的 TypeScript 程序

下面我们就来写一个最简单的 TypeScript程序,了解一下整个使用过程。咱们还是以 Helloworld 为例:

1
2
3
4
5
6
function hello(person: string) {
return 'Hello , ' + person;
}

let user='xxx'
console.log(hello(user));

上面就是一个简单的 TypeScript脚本,有了这个脚本后我们需要先对其进行编译,编译执行下面的命令:

1
tsc hello.ts

编译出 JavaScript 脚本后,通过 HTML5 引用一下就好了,代码如下:

1
2
3
4
5
6
7
8
<head>
<head>
<title>user typescript</title>
</head>
<body>
<script type="text/javascript" src="./hellots.js"></script>
</body>
</head>

至此,一个 TypeScript的简单使用过程就完成了,还是蛮简单的对吧!

定义一个类

使用TypeScript定义类非常简单,这里我们直接看代码就好了:

1
2
3
4
5
6
7
8
9
10
class MyClass {
id : number
msg: string

//构造函数
constructor(id: number, msg: string){
this.id = id
this.msg = msg
}
}

上面我定义了一个MyClass 类,它包括id和msg两个成员,其中id是数值型,而msg是字符串型。

在这个类中有一个构造函数,即 constructor,我们需要在这个函数中对类中的成员变量进行初始化。

TS 调用JS

我们在使用TS开发时最常见的一个问题是如何通过 TS 调用 JS。产生该问题的根本原因是一些著名的 JS 库(如VUE)的TS版本还没有开发出来,但我们的项目中又必须使用他们,因此就产生了我前面所说的TS 库要调用 JS 库的情况。

我们前面也讲了 TS 本来就是 JS 的一个超集,因此它是有办法调用JS库的。从原理上我们可以证明这一点,因为TS程序最终要经过编译生成JS脚本程序后才能被浏览器执行,因此只要在浏览器上引入它需要的 JS 库,经编译后的 TS 程序就可以与其它的JS库相互调用。

按照上面的描述好像TS 调JS是很简单的事儿,那问题在哪儿呢?其实问题在于如果我们自己写的 TS 程序调用了其它第三方 JS 库,那么正常情况下 tsc 编译我们的 ts 程序时就会报错。所以实际的问题应该是,我们编写的TS程序在调用第三方JS库时,如何可以顺利编译通过呢?

我们在网上可以找到以下几种方案,第一种是将引用到的 JS 库直接翻译成 TS 库。很多同学看到这句话会嗤之以鼻,这明显就是行不通的方案。不过这种方案虽然难度很大,但总归还是一种方案不是;第二种是让tsc编译器不进行类型检查,那也就失去了 TS 的意义,所以这种方法也不是好办法;第三种是为 JS 库增加声名函数,这种方式既可以让tsc在编译时顺利通过,又同时可以检查我们写的代码是否有问题。

所以综上所述,第三种方案是最优的方案。

接下来我就来重点讲解一下如何通过第三种方案实现TS调用第三方JS库。首先我们先来创建一个JS库test.js,代码如下:

1
2
3
function showmsg(msg){
console.log("the msg is :" + msg);
}

上面的代码非常简单,只实现了一个函数。该函数有一个参数msg,当该函数被调用时,输出传入的参数值。

接下来我们来看一下在TS中如何调用JS中的方法。为了使 TS 可以调用JS的方法,我们需要写一个与JS文件名对应的.d.ts文件。对于我们上面的test.js则需要有一个test.d.ts与之对应。

编写.d.ts文件也很简单,对于test.js来说,它的.d.ts文件内容如下:

1
declare function showmsg( msg: string) : void;

只需要这样一句就可以了。实际上,它就是为test.js文件中的showmsg函数定个声名。然后我们在使用它的TS文件中引用这个.d.ts文件就好了。如下所示:

1
2
3
4
5
6
/// <reference path = "./test.d.ts" />
function doSomeThing(){
showmsg('ts');
}

doSomeThing();

在TS文件中引用.d.ts文件的方法是,在文件的开头写上 /// <reference path="./test.d.ts" /> 即可。这样当我们使用tsc去编译.ts文件时就不会报错了。

tsc编译好TS文件后,我们可以在HTML中引入生成的JS文件以及它所使用的JS库了。代码如下:

1
2
3
4
5
6
7
8
9
<html>
<head>
<title> test ts call js</title>
</head>
<body>
<script src="./test.js"></script>
<script src="./my.js"></script>
</body>
</html>

此时,在浏览器的debugger里就可以看到the msg is :ts这句话了。

小结

本文我向你介绍了TypeScript的基本工作原理,从中我们可能知道TypeScript解决了JavaScript最大的问题,即类型检测。但TypeScript并不是一门新语言,它也不会代替JavaScript,它只是JavaScript的一个超集而以。

欢迎关注我的其它发布渠道