TypeScript 是 JavaScript 的一种超集,它允许我们使用静态类型来编写 JavaScript 代码,从而提高代码的可靠性和可维护性。它添加了很多有用的特性,例如类、模块、接口、类型注解等,并且可以让我们利用现代化的 ECMAScript 特性,例如箭头函数、类的成员变量初始化、可选属性等。
TypeScript 的主要优点包括:
-
静态类型检查:通过类型检查能够更早地发现代码中的错误,减少调试时间,提高代码质量。
-
提高可读性和可维护性:静态类型可以增强代码的可读性和可维护性,代码易于理解,易于维护。
-
完善的 IDE 支持:现在很多主流的编辑器和IDE都支持 TypeScript,例如Visual Studio Code、WebStorm、Sublime Text等,它们能够提供代码自动补全、语法检查、重构等强大的功能。
-
简化代码编写:TypeScript 提供了接口、枚举、泛型等高级特性,简化了代码编写和维护。
下面我们来看一些 TypeScript 的具体用法。
数据类型
TypeScript 的数据类型与 JavaScript 类似,但增加了类型注解的特性。在 TypeScript 中我们可以指定变量或函数的参数、返回值等的类型,从而确保代码的正确性。
布尔类型
boolean 类型表示逻辑值,只有两个值,true 和 false。
let isDone: boolean = false;
数字类型
number 类型表示数字,包括整数和小数。
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
字符串类型
string 类型表示字符串,它可以是单引号(')、双引号(")或反引号(`)括起来的一串字符。
let name: string = 'Tom';
let age: number = 18;
let introduction: string = `My name is ${name}, and I'm ${age} years old.`
数组
在 TypeScript 中,可以使用两种方式来定义数组类型。
// 方式一:元素类型 followed by []
let list: number[] = [1, 2, 3];
// 方式二:Array<元素类型>
let list: Array<number> = [1, 2, 3];
元组
元组表示一个已知元素数量和类型的数组,各元素的类型不必相同。元组类型的变量可以使用数组的下标方式访问,也可以使用元素名称方式访问。
let tuple: [string, number] = ['Tom', 18];
let name: string = tuple[0];
let age: number = tuple[1];
枚举
枚举是一种特殊的数据类型,用于表示一组值中的固定数据,通常用于状态码定义、选项定义、状态传递等场景。
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
Any
any 类型表示任意类型,这种类型的变量可以存储任意类型的值。在使用 any 类型时应当慎用,因为这样会使代码变得不可读,也会失去 TypeScript 的类型检查优势。
let anyType: any = 1;
anyType = 'Tom';
anyType = true;
Void
void 类型表示空类型,一般用于函数返回值的类型声明。当一个函数没有返回值时,它的返回类型就是 void。
function sayHello(name: string): void {
console.log(`Hello, ${name}!`)
}
sayHello('Tom');
Null 和 Undefined
在 JavaScript 中,null 和 undefined 代表“没有值”,在 TypeScript 中,这两个类型也被称为 null 类型和 undefined 类型。
let u: undefined = undefined;
let n: null = null;
Never
never 类型表示那些永远不会发生的值。例如,一个函数的返回类型为 never ,那么它要么会抛出一个异常,要么永远不会返回。
function error(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
Object
object 类型表示非原始类型,即除 number、string、boolean、symbol、null 或 undefined 之外的类型。因此,一个对象变量如果被定义为 object 类型,那么它可以存储任意非基本数据类型的值。
let obj: object = {};
obj = function() {};
obj = [];
类
TypeScript 是一个面向对象编程语言,它支持类、继承、封装、抽象类、接口等面向对象特性。
类定义
TypeScript 中使用 class 关键字来定义类。
class Person {
private name: string; // 私有成员变量
constructor(name: string) { // 构造函数
this.name = name;
}
public sayHello() { // 公有方法
console.log(`Hello, ${this.name}!`);
}
}
对象实例化
类定义后,可以使用 new 关键字来创建类实例。
let tom: Person = new Person('Tom');
tom.sayHello();
访问控制
可以使用 public、private 或 protected 关键字来明确变量和方法的访问控制,这些关键字用来控制类成员的可见性。其中,在 TypeScript 中,默认情况下,类成员都是 public 的。
class Person {
private name: string; // 私有成员变量
constructor(name: string) { // 构造函数
this.name = name;
}
public sayHello() { // 公有方法
console.log(`Hello, ${this.name}!`);
}
private getAge() { // 私有方法
return 18;
}
}
继承
继承是面向对象编程中的一个重要概念,它允许我们创建一个新的类,来扩展已有类的功能。在 TypeScript 中,我们可以使用 extends 关键字来实现类之间的继承关系。
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
public move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
constructor(name: string) {
super(name);
}
public move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) {
super(name);
}
public move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
抽象类
抽象类是一种不能被实例化的类,它只能被继承,用于定义一些基础功能或行为规范。在 TypeScript 中,我们可以使用 abstract 关键字来声明抽象类。
abstract class Department {
constructor(public name: string) { }
public printName(): void {
console.log(`Department name: ${this.name}`);
}
abstract printMeeting(): void;
}
class AccountingDepartment extends Department {
constructor() {
super("Accounting and Auditing"); // constructors in derived classes must call super()
}
printMeeting(): void {
console.log("The Accounting Department meets each Monday at 10am.");
}
}