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 課程中進一步探討。

廣告