一文教你如何学习TypeScript

简介: 一文教你如何学习TypeScript

熟练使用JavaScript开发日常项目

一、什么是TypeScript?

94cdaeb50afd0f6a5133af1e95a82542.png

1、TypeScript词解

Typed JavaScript at Any Scale。

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

以上是官网[1]对于 TypeScript 的定义。强调了两个重要特性:

  1. 类型系统
  2. 适用于任何规模


2、TypeScript的特性

1、类型系统

50f11afd80811f8c3937eabe75778719.png

从 TypeScript 的名字就可以看出来,「类型」是其最核心的特性。

我们知道,JavaScript 是一门非常灵活的编程语言(弱类型):

  • 没有类型约束,一个变量可能开始是字符串,过一会儿又被赋值为数字。
  • 隐式转换可以在运行中把变量类型转来转去。
  • 基于原型的面向对象编程,使得原型上的属性或方法可以在运行时被修改。
  • 函数是 JavaScript 中的一等公民,可以赋值给变量,也可以当作参数或返回值。

这种灵活性就像一把双刃剑,一方面使得 JavaScript 蓬勃发展,无所不能(App,桌面、小程序、网站、各种框架、服务端);但在另一方面却因代码参差不齐导致维护成本较高。

而 TypeScript 的类型系统,在很大程度上弥补了 JavaScript 的缺点。


TypeScript 是静态类型

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

动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。JavaScript 是一门解释型语言,没有编译阶段,所以它是动态类型,以下这段代码在运行时才会报错:

let foo = 1;
foo.split(' ');
// Uncaught TypeError: foo.split is not a function
// 运行时会报错(foo.split 不是一个函数),造成线上 bug

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

let foo = 1;
foo.split(' ');
// Property 'split' does not exist on type 'number'.
// 编译时会报错(数字没有 split 方法),无法通过编译

a6a83dd16bd8906579f20bb97eb09b9c.png

这段 TypeScript 代码看上去和 JavaScript 没有什么区别。

实际上大部分 JavaScript 代码都只需要经过少量的修改(或者完全不用修改)就能变成 TypeScript 代码,这得益于 TypeScript 强大的「类型推论」,即使不去手动声明变量 foo 的类型,也能在变量初始化时自动推论出它是一个 number 类型。

完整的 TypeScript 代码是这样的:

let foo: number = 1;
foo.split(' ');
// Property 'split' does not exist on type 'number'.
// 编译时会报错(数字没有 split 方法),无法通过编译

TypeScript 是弱类型

类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型。

以下这段代码不管是在 JavaScript 中还是在 TypeScript 中都是可以正常运行的,运行时数字 1 会被隐式类型转换为字符串 '1',加号 + 被识别为字符串拼接,所以打印出结果是字符串 '11'


console.log(1 + '1');
// 打印出字符串 '11'

TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性,所以它们都是弱类型

作为对比,Python 是强类型,以下代码会在运行时报错:

print(1 + '1')
# TypeError: unsupported operand type(s) for +: 'int' and 'str'

若要修复该错误,需要进行强制类型转换:

print(str(1) + '1')
# 打印出字符串 '11'

JavaScript 和 TypeScript 中不管加号两侧是什么类型,都可以通过隐式类型转换计算出一个结果——而不是报错——所以 JavaScript 和 TypeScript 都是弱类型。

虽然TypeScript是弱类型,但我们可以通过TypeScript提供的类型系统,以及ESLint提供的代码检查功能。使得TypeScript更像是一个「强类型」。

这样的类型系统体现了 TypeScript 的核心设计理念:在完整保留 JavaScript 运行时行为的基础上,通过引入静态类型系统来提高代码的可维护性,减少可能出现的 bug。

2、适用于任何规模

TypeScript 非常适用于大型项目,类型系统可以为大型项目带来更高的可维护性,以及更少的 bug。

在中小型项目中由于有[类型推论],大部分类型都不需要手动声明了,所以不会很大程度的降低开发效率,故部分中小企业也会选择它。

TypeScript 还可以和 JavaScript 共存。如果你是老的JavaScript项目,你想改造成TypeScript的项目,但又代码量太大并且项目要继续更新。那么你可以新的内容和文件用TypeScript,老的不变。当闲下来时,可以逐步将老的一个一个文件的升级为TypeScript。

事实上,就算你从来没学习过 TypeScript,你也可能已经在不知不觉中使用到了 TypeScript——在 VSCode 编辑器中编写 JavaScript 时,代码补全和接口提示等功能就是通过 TypeScript Language Service 实现的:

4f387f7572eb3788706ae4f60ec8f638.png

一些第三方库原生支持了 TypeScript,在使用时就能获得代码补全了,比如 Vue 3.0:

0dad7acb3cef7ff283924cc31adfc5e3.jpg

有一些第三方库原生不支持 TypeScript,但是可以通过安装社区维护的类型声明库(比如通过运行 npm install --save-dev @types/react 来安装 React 的类型声明库)来获得代码补全能力——不管是在 JavaScript 项目中还是在 TypeScript 中项目中都是支持的:

027d0f2387139214d6eab126d43248df.png

由此可见,TypeScript 的发展已经深入到前端社区的方方面面了,任何规模的项目都或多或少得到了 TypeScript 的支持。

3、与标准同步发展

TypeScript 的另一个重要的特性就是坚持与 ECMAScript 标准同步发展。


ECMAScript 是 JavaScript 核心语法的标准,自 2015 年起,每年都会发布一个新版本,包含一些新的语法。

一个新的语法从提案到变成正式标准,需要经历以下几个阶段:

  • Stage 0:展示阶段,仅仅是提出了讨论、想法,尚未正式提案。
  • Stage 1:征求意见阶段,提供抽象的 API 描述,讨论可行性,关键算法等。
  • Stage 2:草案阶段,使用正式的规范语言精确描述其语法和语义。
  • Stage 3:候选人阶段,语法的设计工作已完成,需要浏览器、Node.js 等环境支持,搜集用户的反馈。
  • Stage 4:定案阶段,已准备好将其添加到正式的 ECMAScript 标准中。

一个语法进入到 Stage 3 阶段后,TypeScript 就会实现它。一方面,让我们可以尽早的使用到最新的语法,帮助它进入到下一个阶段;另一方面,处于 Stage 3 阶段的语法已经比较稳定了,基本不会有语法的变更,这使得我们能够放心的使用它。

除了实现 ECMAScript 标准之外,TypeScript 团队也推进了诸多语法提案,比如可选链操作符(?.)、空值合并操作符(??)、Throw 表达式、正则匹配索引等。


3、怎么安装TypeScript和编辑器推荐

1、安装 TypeScript

TypeScript 的命令行工具安装方法如下:

npm install -g typescript
# 或者用yarn

以上命令会在全局环境下安装 tsc 命令,安装完成之后,我们就可以在任何地方执行 tsc 命令了。

编译一个 TypeScript 文件很简单:

tsc hello.ts

我们约定使用 TypeScript 编写的文件以 .ts 为后缀,用 TypeScript 编写 React 时,以 .tsx 为后缀。

2、编辑器

TypeScript 最大的优势之一便是增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等。

主流的编辑器都支持 TypeScript,这里我推荐使用 Visual Studio Code(前端开发神器)

它是一款开源,跨终端的轻量级编辑器,内置了对 TypeScript 的支持。无需要编译阶段,写完就能看到对不对。

06fad2f396614c5fcb003822ab5606ef.png

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6acs5DXl-1635497989842)(<> “点击并拖拽以移动”)]

上图写完就报了错误,因为number没有length属性。

另外vscode本身也是用 TypeScript 编写的。

下载安装:Visual Studio Code - Code Editing. Redefined

4、第一个案例Hello TS

我们从一个简单的例子开始。

将以下代码复制到 hello.ts 中:

function sayHello(person: string) {
    return 'Hello, ' + person;
}
let user = 'TS';
console.log(sayHello(user));

然后执行

tsc hello.ts

这时候会生成一个编译好的文件 hello.js

function sayHello(person) {
    return 'Hello, ' + person;
}
var user = 'TS';
console.log(sayHello(user));

在 TypeScript 中,我们使用 : 指定变量的类型,: 的前后有没有空格都可以。

上述例子中,我们用 : 指定 person 参数类型为 string。但是编译为 js 之后,并没有什么检查的代码被插入进来。

这是因为 TypeScript 只会在编译时对类型进行静态检查,如果发现有错误,编译(ts文件转换成js的过程)的时候就会报错。而在运行时,与普通的 JavaScript 文件一样,不会对类型进行检查。

如果我们需要保证运行时的参数类型,还是得手动对类型进行判断:

function sayHello(person: string) {
    if (typeof person === 'string') {
        return 'Hello, ' + person;
    } else {
        throw new Error('person is not a string');
    }
}
let user = 'TS';
console.log(sayHello(user));

下面尝试把这段代码编译一下:

function sayHello(person: string) {
    return 'Hello, ' + person;
}
let user = [0, 1, 2];
console.log(sayHello(user));

编辑器中会提示错误,编译的时候也会出错:

37df7e9a36d95ac2a7c8d1145982a2e8.png

但是还是生成了 js 文件:

function sayHello(person) {
    return 'Hello, ' + person;
}
var user = [0, 1, 2];
console.log(sayHello(user));

这是因为 TypeScript 编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译之后的文件。

如果要在报错的时候终止 js 文件的生成,可以在 tsconfig.json 中配置 noEmitOnError 即可。关于 tsconfig.json,请参阅官方手册中文版)。 后面会在TypeScript基础的原始数据类型[数值]中说明sconfig.json怎么来的!

二、TypeScript基础

1、原始数据类型

原始数据类型 · TypeScript

PS:空值中:

void 的区别是,undefinednull 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:(需要tsconfig.json中strict设置为false)

2、任意值

任意值 · TypeScript

3、类型推论

类型推论 · TypeScript

4、联合类型

联合类型 · TypeScript

PS:需要注意的是,一旦定义了可选属性,那么同一个接口内其他所有的属性,都只能是可选属性的子集,否则将会报错 !集合概念:string | number 为例,number为它的子集,string也为它的子集。

另一个版本问题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dRdWMx1b-1635497989845)(<> “点击并拖拽以移动”)]

5、对象的类型—接口

对象的类型——接口 · TypeScript

6、数组的类型

数组的类型 · TypeScript

PS:疑惑? {

   [index: number]: number;

   length: number;

   callee: Function;

}

中任意类型为number为什么 callee可以是Function?

7、函数的类型

函数的类型 · TypeScript

8、类型断言

类型断言 · TypeScript

9、声明文件

声明文件 · TypeScript

10、内置对象

内置对象 · TypeScript

三、TypeScript进阶

进阶 · TypeScript

四、总结

咳,偷个懒,不一一列举。还是那句话,对于TypeScript 入门教程这本书我是极其推荐的,学 TypeScript 还是得看它。除了以上的内容外,它还囊括了工程化配置说明。我以我学弟的人格担保,看它必会!冲啊xdm!






相关文章
|
7月前
|
JavaScript 前端开发 编译器
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)
135 0
|
7月前
|
编解码 JavaScript 前端开发
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
TypeScript【第三方声明文件、自定义声明文件、tsconfig.json文件简介、tsconfig.json 文件结构与配置】(六)-全面详解(学习总结---从入门到深化)
367 0
|
7月前
|
JavaScript
TypeScript【类的继承、访问修饰符、readonly 修饰符、存取器、实例方法与静态方法、实例属性与静态属性、静态属性、抽象类】(三)-全面详解(学习总结---从入门到深化)
TypeScript【类的继承、访问修饰符、readonly 修饰符、存取器、实例方法与静态方法、实例属性与静态属性、静态属性、抽象类】(三)-全面详解(学习总结---从入门到深化)
70 0
|
3月前
|
JavaScript
typeScript基础(1)_原始数据类型学习
本文介绍了TypeScript中的原始数据类型,包括布尔型、数值型、字符串型、`void`、`null`和`undefined`,并展示了如何在TypeScript中声明和使用这些类型。同时,还介绍了如何通过`tsc`命令编译TypeScript文件。
55 4
|
2月前
|
JavaScript 索引
TypeScript(TS)安装指南与基础教程学习全攻略(二)
TypeScript(TS)安装指南与基础教程学习全攻略(二)
59 0
|
2月前
|
JavaScript 前端开发 安全
TypeScript(TS)安装指南与基础教程学习全攻略(一)
TypeScript(TS)安装指南与基础教程学习全攻略(一)
31 0
|
5月前
|
JavaScript 前端开发 安全
如何学习typescript?
【7月更文挑战第9天】1. 了解其为JavaScript超集,增加类型系统和ES6特性,提升代码安全性和效率。 2. 安装 TypeScript 全局 (`npm install -g typescript`),用`tsc -v`验证,或尝试在线的TypeScript Playground。 3. 学习类型注解、基础类型(如number、string、boolean等)、any与unknown,接口和类。 4. 探索高级特性,如泛型、模块&命名空间、装饰器。 5. 实践中巩固知识,如做小项目(如用React或Vue),阅读官方文档,参与社区讨论。持续编码和实践是关键。
42 0
|
7月前
|
JavaScript 前端开发 编译器
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)(下)
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)
62 0
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)(下)
|
7月前
|
JavaScript
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)(上)
TypeScript【泛型1、泛型2、声明合并、命名空间 、模块1、模块2、声明文件简介】(五)-全面详解(学习总结---从入门到深化)
79 0
|
7月前
|
JavaScript 前端开发 编译器
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
TypeScript【可选属性、只读属性、额外的属性检查、函数类型、类类型、继承接口】(四)-全面详解(学习总结---从入门到深化)
78 0