什么是 Typescript?
TypeScript
是 javascript
的超集TypeScript
和 Javascript
一样吗?
既是也不是。TypeScript
是由 Microsoft
创建的,并且建立在 javascript
之上。
简而言之,它与 Javascript
相同,但增加了一些功能。
你从 Javascript
中了解的所有内容在 TypeScript
中都会有用。
我应该先学哪一个?
你肯定会先学习 Javascript
。如果你不了解 Javascript
,那么你将很难学习和理解 TypeScript
。
为什么要创建一种新语言?Javascript
没问题,不是吗?
当人们开始在复杂的应用程序中使用 JavaScript
时,他们很快意识到 JavaScript
在 OOP
方面变得难以使用,并且很难找到一些错误。TypeScript
是由 Microsoft
开发的,用于弥补这一差距。
那么 TypeScript
究竟为 javascript
添加了什么?
- 强大的类型系统
- 开发时进行类型错误检查
- 好的面向对象编程
- 新功能,如接口、泛型等。
- 元编程,如装饰器
- 编译为可在旧浏览器上运行的
javascript
- 编辑器中的代码自动完成
- 还有更多…
还有什么我应该知道的?TypeScript
不能像 Javascript
那样在浏览器中或与 node.js
一起运行。要执行,TypeScript
需要转换/编译为 Javascript
。
使用 TypeScript
需要使用编译器。例如,如果你有一个文件名 app.ts
,TypeScript
编译器将创建 javascript
等效的 app.js
。它将用于运行你的应用程序。
这就是为什么我们说 TypeScript
在开发时有帮助。
如何安装和使用 TypeScript
编译器
你可以使用此命令在开发机器上全局安装 TypeScript
1 | npm install -g typescript |
执行编译器
1 | $ tsc app.js |
在监视模式下,每次保存时,TypeScript
都会自动在 app.js
中重新编译 app.ts
。
TypeScript 配置
TypeScript
有很多可用的配置/设置。我不会在这篇介绍文章中介绍这些,只是想让你知道 TypeScript
设置存储在一个名为 tsconfig.json
的文件中。你可以使用以下命令创建此文件
1 | tsc --int |
TypeScript 学习
你现在将学习如何使用基本的 TypeScript
功能
核心类型
TypeScript
最有价值的功能之一是类型系统。在 TypeScript
中,你可以将类型分配给变量,如果代码中任何地方不遵循该类型,TypeScript
编译器将抛出错误。
为了了解类型,我们将进行 TypeScript
与 Javascript
的比较。
这是常规的 Javascript
代码
1 | function add(num1, num2) { |
在此示例中,result1 将为 30,result2 将为 1020
为什么 result2 不是 30?
由于你提供了双引号,因此 Javascript
认为你的参数是字符串,因此会使用该逻辑执行代码而不会报告任何错误。
现在想象一下这种错误会对会计应用程序造成什么样的损害。在 10 万行代码的 Web
应用程序中查找这种错误非常困难、令人沮丧且耗时。
TypeScript
来救场!
让我们使用上面相同的代码,但使用 TypeScript
唯一的区别是参数名称后面添加了 :number
类型
在此示例中,’const result2 = add(“10”, “20”)’ 行将在代码编辑器和编译时报告错误。
类型推断
当初始化变量时,TypeScript
可以自动推断/检测变量的类型
1 | let amount: number = 99.95; |
两个变量都是数字类型。最佳做法是让 TypeScript
推断完成其工作,因为我们自己设置了初始值。这有助于避免重复代码。
请注意,我们仅在变量未用值初始化时指定类型
1 | let title: string; |
对象类型
TypeScript
也会自动推断对象类型
1 | const person = { |
将导致 TypeScript
对象类型
1 | const person: { |
数组类型
声明数组的语法是:类型
1 | const names: string[] = ["William", "John", "Paul"]; |
元组类型
当我们需要数组中固定数量的值时使用。
1 | const names: [number, string] = [100, "William"]; |
枚举类型
枚举主要用于给常量分配名称
1 | enum Role { ADMIN, READ_ONLY, AUTHOR } |
还可以指定 key
(key 可以是任意类型)
1 | enum Role { ADMIN = 100, READ_ONLY = 200, AUTHOR = 300 } |
任何类型
如果你确实不知道类型,请使用 any
作为后备。
1 | let title: any; |
请注意这不是一个好的做法。尽量避免!
联合类型
变量可以灵活地分配两种类型
1 | function combine(item1: string | number, item2: string | number) { |
联合类型的语法是:type2 | type2
类型别名
我们可以创建一个自定义类型作为别名,例如联合类型
1 | type Dual = number | string; |
对象类型别名
1 | type User = { name: string; age: number } |
函数返回类型
我们可以指定函数的返回类型
1 | function add(num1: number, num2: number): number { |
void
返回类型
当函数不返回任何值时,TypeScript
将推断该函数为“void”类型
1 | function displayMessage(): void { |
函数类型
声明语法为:(var: type, var: type) ⇒ 返回类型
1 | function add(num1: number, num2: number): number { |
未知类型
除非我们检查赋值的类型,否则类型未知的变量将无法赋值。
1 | let userInput: unknown; |
TypeScript 中的 OOP
类声明
1 | class Product { |
简写属性初始化
1 | class Product { |
访问修饰符
1 | class Product { |
public 关键字是可选的,因为如果没有提供,它是默认修饰符。
- public 表示类外可用的变量或函数
- private 表示类外不可用的变量或函数
- readonly 表示变量为 private 和 readonly
- protected 表示仅在类或子类内可用的变量或函数
继承
1 | class Friends extends Person {} |
Getters 和 Setters
1 | class Friend { |
静态属性和方法
1 | class Product { |
接口
1 | interface IsPerson { |
1 | const me: IsPerson = { |
1 | class customer implements IsPerson { |
泛型
编写程序时,最重要的方面之一是构建可重用组件。这可确保程序具有灵活性,并且长期可扩展。
泛型提供了一种创建可重用组件的方法。泛型提供了一种使组件能够处理任何数据类型而不局限于一种数据类型的方法。因此,组件可以与各种数据类型一起调用或使用。
例如,如果我们想创建一个具有可以包含不同对象类型的数据属性的接口
首先创建接口
1 | interface Person<T> { |
<T>
是 TypeScript
在编译时添加的类型的占位符
然后你可以在代码中使用通用接口
1 | const person1: Person<string> = { |
在上面的例子中,使用了相同的接口来存储字符串和字符串数组。