TypeScript - 特性



TypeScript 是 JavaScript 的超集。因此,它包含 JavaScript 的所有特性。然而,它也包含一些 JavaScript 没有的高级特性,例如静态类型、接口等。

让我们讨论一些 TypeScript 的重要特性。

类型注解

在 TypeScript 中,类型注解允许您声明变量、函数参数和返回值的类型。TypeScript 的静态类型特性允许您在编写代码时而不是在编译时捕获与类型相关的错误。这样,开发人员可以编写更可靠的代码。

示例

在下面的代码中,我们定义了一个名为 'a' 的数字类型变量。printNumber() 函数接受 'number' 类型的 'num' 参数。

该函数打印参数值。

// Type annotation in TypeScript
var a: number = 10;
function printNumber(num: number) {
  console.log(num);
}
printNumber(a);

编译后,它将生成以下 JavaScript 代码。

// Type annotation in TypeScript
var a = 10;
function printNumber(num) {
    console.log(num);
}
printNumber(a);

输出

以上示例代码将产生以下输出:

10

接口

接口类似于 Java 等其他编程语言中的抽象类。它允许开发人员定义对象的结构,但不提供实现。这样,开发人员可以遵守相同对象的结构以用于类似的对象。

示例

在下面的示例中,我们定义了一个包含 'firstName' 和 'lastName' 属性以及 getFullName() 方法的 'Iperson' 接口。该接口只声明属性和方法,定义对象的结构。

对于 'obj' 对象,我们使用 'IPerson' 接口作为类型。之后,我们初始化对象的属性并实现了返回字符串值的 getFullName() 方法。

// Interfaces in TypeScript
interface IPerson {
  firstName: string;
  lastName: string;
  getFullName(): string;
}

// Define an object that implements the interface
let obj: IPerson = {
  firstName: "John",
  lastName: "Doe",
  getFullName(): string {
    return this.firstName + " " + this.lastName;
  }
};
console.log(obj.getFullName());

编译后,它将生成以下 JavaScript 代码。

// Define an object that implements the interface
let obj = {
   firstName: "John",
   lastName: "Doe",
   getFullName() {
      return this.firstName + " " + this.lastName;
   }
};
console.log(obj.getFullName());

输出

以上示例代码的输出如下:

John Doe

类是对象的蓝图。类可以包含属性和方法,可以使用类的实例访问这些属性和方法。您可以使用 class constructor() 在创建类的实例时初始化类的属性。此外,您还可以在类中拥有静态成员,这些成员可以通过类名访问,而无需使用类的实例。

示例

在下面的代码中,我们创建了 Greeter 类,它包含 'greeting' 属性。constructor() 方法接受 'message' 参数并用它初始化 'greeting' 属性值。

greet() 方法返回一个字符串值,表示问候消息。之后,我们创建了 Greeter 类的实例并使用它调用了 greet() 方法。

// Basic example of class
class Greeter {
  greeting: string;
  // Constructor method
  constructor(message: string) {
    this.greeting = message;
  }
  // Class Method
  greet() {
    return "Hello, " + this.greeting;
  }
}

// Create an instance of the class
let greeter = new Greeter("world");
console.log(greeter.greet()); // Hello, world

编译后,它将生成以下 JavaScript 代码。

// Basic example of class
class Greeter {
    // Constructor method
    constructor(message) {
        this.greeting = message;
    }
    // Class Method
    greet() {
        return "Hello, " + this.greeting;
    }
}
// Create an instance of the class
let greeter = new Greeter("world");
console.log(greeter.greet()); // Hello, world

输出

以上示例代码的输出如下:

Hello, world

继承

TypeScript 支持面向对象编程语言的所有特性,例如多态性、抽象性、封装性和继承性等。但是,在本课中我们只介绍了继承。

继承允许您重用其他类的属性和方法。

示例

在下面的代码中,'Person' 类是基类。它包含 'name' 属性,我们在 constructor() 方法中初始化它。display() 方法在控制台中打印名称。

Employee 类使用 'extends' 关键字继承 Parent 类的属性。它包含 'empCode' 属性和 show() 方法。它还包含 Person 类中的所有属性和方法。

接下来,我们创建了 Employee 类的实例并使用它访问了 Person 类的方法。

// Base class
class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  display(): void {
    console.log(this.name);
  }
}

// Derived class
class Employee extends Person {
  empCode: number;
  constructor(name: string, code: number) {
    super(name);
    this.empCode = code;
  }
  show(): void {
    console.log(this.empCode);
  }
}

let emp: Employee = new Employee("John", 123);
emp.display(); // John
emp.show(); // 123

编译后,它将生成以下 JavaScript 代码。

// Base class
class Person {
    constructor(name) {
        this.name = name;
    }
    display() {
        console.log(this.name);
    }
}
// Derived class
class Employee extends Person {
    constructor(name, code) {
        super(name);
        this.empCode = code;
    }
    show() {
        console.log(this.empCode);
    }
}
let emp = new Employee("John", 123);
emp.display(); // John
emp.show(); // 123

输出

以上示例代码的输出如下:

John
123

枚举

枚举用于在 TypeScript 中定义命名常量。它允许您为常量值命名,这使得代码更可靠且更易读。

示例

在下面的代码中,我们使用了 'enum' 关键字来定义枚举。在我们的例子中,整数表示方向,但是为了更好的可读性,我们为方向命名了。

之后,您可以使用常量名来访问 Directions 的值。

// Enums in TypeScript
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

console.log(Direction.Up); // 1
console.log(Direction.Down); // 2
console.log(Direction.Left); // 3
console.log(Direction.Right); // 4

编译后,它将生成以下 JavaScript 代码:

var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 1] = "Up";
    Direction[Direction["Down"] = 2] = "Down";
    Direction[Direction["Left"] = 3] = "Left";
    Direction[Direction["Right"] = 4] = "Right";
})(Direction || (Direction = {}));
console.log(Direction.Up); // 1
console.log(Direction.Down); // 2
console.log(Direction.Left); // 3
console.log(Direction.Right); // 4

输出

以上示例代码的输出如下:

1
2
3
4

泛型

泛型类型允许您创建可重用的组件、函数代码或类,这些组件、函数代码或类可以与不同的类型一起工作,而不是与特定类型一起工作。这样,开发人员可以使用相同的功能或类处理多种类型。

示例

在下面的代码中,printArray() 是一个泛型函数,它有一个类型参数。它将 Type 'T' 的数组作为参数。该函数使用 for 循环来打印数组元素。

接下来,我们通过传递数字和字符串数组来调用该函数。您可以观察到该函数将任何类型的数组作为参数。这样,开发人员就可以对不同类型使用相同的代码。

// Generics in TypeScript
function printArray(arr: T[]): void {
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
}
printArray([1, 2, 3]); // Array of numbers
printArray(["a", "b", "c"]); // Array of strings

编译后,它将生成以下 JavaScript 代码。

// Generics in TypeScript
function printArray(arr) {
    for (let i = 0; i < arr.length; i++) {
        console.log(arr[i]);
    }
}
printArray([1, 2, 3]); // Array of numbers
printArray(["a", "b", "c"]); // Array of strings

输出

以上示例代码的输出如下:

1
2
3
a
b
c

联合类型

联合类型允许您为变量声明多个类型。有时,开发人员需要定义一个支持数字、字符串、null 等类型的单个变量。在这种情况下,他们可以使用联合类型。

示例

在下面的代码中,'unionType' 具有字符串和数字类型。它可以存储这两种类型的任何值,但如果您尝试存储任何其他类型的任何值,如布尔值,TypeScript 编译器将抛出错误。

// Union types in TypeScript
var unionType: string | number;
unionType = "Hello World"; // Assigning a string value
console.log("String value: " + unionType);

unionType = 500; // Assigning a number value
console.log("Number value: " + unionType);

// unionType = true; // Error: Type 'boolean' is not assignable to type 'string | number'

编译后,它将生成以下 JavaScript 代码。

// Union types in TypeScript
var unionType;
unionType = "Hello World"; // Assigning a string value
console.log("String value: " + unionType);
unionType = 500; // Assigning a number value
console.log("Number value: " + unionType);
// unionType = true; // Error: Type 'boolean' is not assignable to type 'string | number'

输出

以上示例代码的输出如下:

String value: Hello World
Number value: 500

类型守卫

类型守卫允许您获取变量的类型。之后,您可以根据特定变量的类型执行多个操作。这也确保了类型安全。

示例

在下面的代码中,我们定义了一个数字和字符串类型的变量 'a'。

之后,我们使用 if-else 语句和 'typeof' 运算符获取变量 'a' 的类型。根据 'a' 的类型,我们在控制台中打印字符串值。

let a: number | string = 10;
// Type Guard
if (typeof a === 'number') {
  console.log('a is a number');
} else {
  console.log('a is a string');
}

编译后,它将生成以下 JavaScript 代码。

let a = 10;
// Type Guard
if (typeof a === 'number') {
    console.log('a is a number');
}
else {
    console.log('a is a string');
}

输出

以上示例代码的输出如下:

a is a number

在本课中,我们介绍了 TypeScript 的最重要特性。TypeScript 还包含可选链、装饰器、模块、类型接口等特性,我们将在本 TypeScript 课程中进一步探讨。

广告