简述

TypeScript 是 JavaScript 的一个超集,它在 JavaScript 的基础上增加了类型系统和更强大的面向对象编程支持。有趣的是它将JS这样的动态类型语言变成了动态类型语言。

参考:

TypeScript-文档

优势

以下是ChatGTP给出的答案,结合我自己的理解就是,TS相比JS来说和用IDEA编程Java语言一样,可以自动补全,导航(快速跳转至自定义变量、方法、类等标识符的位置),类型检查(编译时检查类型错误/编辑代码时显示类型错误)、重构(智能地重命名变量、方法、类等标识符)。

参考:

TypeScript-文档:5分钟上手TypeScript

  • 类型系统: TypeScript 提供了静态类型检查,可以在编译时发现很多常见的错误,例如类型错误、拼写错误等。这使得代码更加健壮和可维护。同时,类型系统还使得编辑器和 IDE 更加智能,可以提供更好的代码补全、重构等功能。

  • 更好的面向对象编程支持: TypeScript 提供了更好的面向对象编程支持,包括封装、继承、接口、抽象类等。这使得编写复杂的应用程序更加容易和可维护。

  • 更好的工具支持: 由于 TypeScript 提供了静态类型检查,IDE 和编辑器可以更好地支持自动补全、重构、代码格式化等功能,这使得开发效率得到了显著提高。

  • 渐进式应用: TypeScript 是渐进式的,可以与 JavaScript 代码混用,可以一步一步将 JavaScript 代码迁移到 TypeScript,这保证了代码的兼容性和可维护性。

  • 更好的文档体验: TypeScript 可以为代码添加类型注解和 JSDoc 注释,这使得代码的文档更加完整和清晰。同时,TypeScript 还提供了更好的声明文件支持,可以为第三方库提供类型定义文件,这提高了代码的可维护性和可读性。

初识

npm安装

1
> npm install -g typescript

编译

安装typescript后可将.ts语言文件编译成.js语言文件

1
tsc greeter.ts

编译完成后你可在greeter.ts所在的目录下看到greeter.js文件

代码分析

静态类型

testStaticType.ts

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

let user = [0, 1, 2];

document.body.innerHTML = greeter(user);

以上类型注释的静态类型是string,如果你学过Java,如果传入一个数组,编译是不会通过的,此时是TS就会编译通过,打印出警告,并成JS文件如下:

警告

1
2
3
4
5
6
testStaticType.ts:7:35 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

7 document.body.innerHTML = greeter(user);
~~~~

Found 1 error in testStaticType.ts:7

testStaticType.js

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

let user = [0, 1, 2];

document.body.innerHTML = greeter(user);

运行结果浏览器中打印Hello, 0,1,2

接口

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.innerHTML = greeter(user);
  • 在TypeScript里,只在两个类型内部的结构兼容那么这两个类型就是兼容的。 这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,进一步理解看下一个代码分析中的class Student其中满足上述接口的两个参数即可
  • 不必明确地使用 implements语句

test.ts

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, public middleInitial, public lastName) {
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.innerHTML = greeter(user);

知识点

  • 在构造函数的参数上使用public等同于创建了同名的成员变量
  • person : Person其实不是继承接口,作用是用来限制类型的,这里限制的类型为Person接口,只需满足传入的类中包含接口中的属性即可

编译后test.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);

知识点

  • this.的意思是,哪行代码newStudent,此行代码new的这个对象中就会被赋值成员变量firstName、middleInitial、lastName、fullName

  • 立即调用函数表达式(IIFE)

    1
    2
    3
    var Student = (function () {
    /** 立即执行的代码块 */
    }());

    我们定义了一个名为 Student 的类作为返回值。这个类定义完成后立即返回,返回的值将会被赋给 var Student 变量。这种方式可以让我们在不污染全局作用域的情况下使用这个 Student