
- TypeScript 基礎
- TypeScript - 首頁
- TypeScript - 路線圖
- TypeScript - 概述
- TypeScript - 環境搭建
- TypeScript - 基本語法
- TypeScript vs. JavaScript
- TypeScript - 特性
- TypeScript - 變數
- TypeScript - let & const
- TypeScript - 運算子
- TypeScript 基本型別
- TypeScript - 型別
- TypeScript - 型別註解
- TypeScript - 型別推斷
- TypeScript - 數字
- TypeScript - 字串
- TypeScript - 布林值
- TypeScript - 陣列
- TypeScript - 元組
- TypeScript - 列舉
- TypeScript - any
- TypeScript - never
- TypeScript - 聯合型別
- TypeScript - 字面量型別
- TypeScript - Symbols
- TypeScript - null vs. undefined
- TypeScript - 類型別名
- TypeScript 控制流
- TypeScript - 決策
- TypeScript - if 語句
- TypeScript - if else 語句
- TypeScript - 巢狀 if 語句
- TypeScript - switch 語句
- TypeScript - 迴圈
- TypeScript - for 迴圈
- TypeScript - while 迴圈
- TypeScript - do while 迴圈
- TypeScript 函式
- TypeScript - 函式
- TypeScript - 函式型別
- TypeScript - 可選引數
- TypeScript - 預設引數
- TypeScript - 匿名函式
- TypeScript - 函式構造器
- TypeScript - rest 引數
- TypeScript - 引數解構
- TypeScript - 箭頭函式
- TypeScript 介面
- TypeScript - 介面
- TypeScript - 介面擴充套件
- TypeScript 類和物件
- TypeScript - 類
- TypeScript - 物件
- TypeScript - 訪問修飾符
- TypeScript - 只讀屬性
- TypeScript - 繼承
- TypeScript - 靜態方法和屬性
- TypeScript - 抽象類
- TypeScript - 訪問器
- TypeScript - 鴨子型別
- TypeScript 高階型別
- TypeScript - 交叉型別
- TypeScript - 型別保護
- TypeScript - 型別斷言
- TypeScript 型別操作
- TypeScript - 從型別建立型別
- TypeScript - keyof 型別運算子
- TypeScript - typeof 型別運算子
- TypeScript - 索引訪問型別
- TypeScript - 條件型別
- TypeScript - 對映型別
- TypeScript - 模板字面量型別
- TypeScript 泛型
- TypeScript - 泛型
- TypeScript - 泛型約束
- TypeScript - 泛型介面
- TypeScript - 泛型類
- TypeScript 其他
- TypeScript - 三斜槓指令
- TypeScript - 名稱空間
- TypeScript - 模組
- TypeScript - 環境宣告
- TypeScript - 裝飾器
- TypeScript - 型別相容性
- TypeScript - Date 物件
- TypeScript - 迭代器和生成器
- TypeScript - Mixins
- TypeScript - 實用型別
- TypeScript - 裝箱和拆箱
- TypeScript - tsconfig.json
- 從 JavaScript 到 TypeScript
- TypeScript 有用資源
- TypeScript 快速指南
- TypeScript - 有用資源
- TypeScript - 討論
TypeScript 快速指南
TypeScript - 概述
JavaScript 最初被設計為客戶端語言。Node.js 的發展也標誌著 JavaScript 成為一種新興的伺服器端技術。然而,隨著 JavaScript 程式碼的增長,它往往會變得越來越混亂,難以維護和重用程式碼。此外,它未能採用面向物件特性、強型別檢查和編譯時錯誤檢查,這使得 JavaScript 無法在企業級成為成熟的伺服器端技術。TypeScript 正是為了彌補這一差距而出現的。
什麼是 TypeScript?
根據定義,“TypeScript 是用於應用程式規模開發的 JavaScript”。
TypeScript 是一種強型別的、面向物件的、編譯型語言。它由微軟的Anders Hejlsberg(C# 的設計者)設計。TypeScript 既是一種語言,也是一組工具。TypeScript 是 JavaScript 的型別化超集,編譯成 JavaScript。換句話說,TypeScript 是 JavaScript 加上一些附加特性。

TypeScript 的特性
TypeScript 本質上是 JavaScript。TypeScript 從 JavaScript 開始,最終也得到 JavaScript。TypeScript 從 JavaScript 採用程式的基本構建塊。因此,你只需要瞭解 JavaScript 就可以使用 TypeScript。所有 TypeScript 程式碼都會轉換為等效的 JavaScript 程式碼以供執行。
TypeScript 支援其他 JS 庫。編譯後的 TypeScript 可以從任何 JavaScript 程式碼中使用。TypeScript 生成的 JavaScript 可以重用所有現有的 JavaScript 框架、工具和庫。
JavaScript 就是 TypeScript。這意味著任何有效的.js檔案都可以重新命名為.ts檔案,並與其他 TypeScript 檔案一起編譯。
TypeScript 是可移植的。TypeScript 可跨瀏覽器、裝置和作業系統移植。它可以在任何 JavaScript 可以執行的環境中執行。與其他語言不同,TypeScript 不需要專用的虛擬機器或特定的執行時環境來執行。
TypeScript 和 ECMAScript
ECMAScript 規範是指令碼語言的標準化規範。已經發布了六個版本的 ECMA-262。標準的第 6 版代號為“Harmony”。TypeScript 與 ECMAScript 6 規範保持一致。

TypeScript 從 ECMAScript 5 規範(即 JavaScript 的官方規範)中採用了其基本語言特性。TypeScript 的語言特性,如模組和基於類的面向物件,與 EcmaScript 6 規範一致。此外,TypeScript 還包含泛型和型別註解等特性,這些特性並非 EcmaScript 6 規範的一部分。
為什麼要使用 TypeScript?
TypeScript 比其他類似語言,如 CoffeeScript 和 Dart 程式語言更勝一籌,因為它擴充套件了 JavaScript。相比之下,Dart 和 CoffeeScript 等語言本身就是新的語言,需要特定於語言的執行環境。
TypeScript 的好處包括:
編譯 - JavaScript 是一種解釋型語言。因此,需要執行它才能測試其有效性。這意味著你編寫所有程式碼只是為了發現沒有輸出,如果存在錯誤的話。因此,你必須花費數小時的時間來查詢程式碼中的錯誤。TypeScript 編譯器提供錯誤檢查功能。如果 TypeScript 發現任何語法錯誤,它將編譯程式碼並生成編譯錯誤。這有助於在指令碼執行之前突出顯示錯誤。
強靜態型別 - JavaScript 不是強型別語言。TypeScript 透過 TLS(TypeScript 語言服務)提供可選的靜態型別和型別推斷系統。未宣告型別的變數的型別可能由 TLS 根據其值推斷。
TypeScript支援現有 JavaScript 庫的型別定義。TypeScript 定義檔案(副檔名為.d.ts)為外部 JavaScript 庫提供定義。因此,TypeScript 程式碼可以包含這些庫。
TypeScript支援面向物件程式設計概念,如類、介面、繼承等。
TypeScript 的組成部分
TypeScript 的核心包含以下三個組成部分:
語言 - 包括語法、關鍵字和型別註解。
TypeScript 編譯器 - TypeScript 編譯器 (tsc) 將 TypeScript 編寫的指令轉換為等效的 JavaScript 程式碼。
TypeScript 語言服務 - “語言服務”在核心編譯器管道周圍提供了一個額外的層,這些層是類似編輯器的應用程式。語言服務支援典型編輯器操作的常用集合,例如語句完成、簽名幫助、程式碼格式化和概述、著色等。

宣告檔案
當 TypeScript 指令碼被編譯時,可以選擇生成一個宣告檔案(副檔名為.d.ts),該檔案充當編譯後的 JavaScript 中元件的介面。宣告檔案的概念類似於 C/C++ 中的標頭檔案。宣告檔案(副檔名為.d.ts的檔案)為 jQuery、MooTools 等 JavaScript 庫提供型別、函式呼叫和變數的智慧感知。
TypeScript - 環境搭建
我們已經線上設定了 TypeScript 程式設計環境,以便你可以在進行理論學習的同時線上執行所有可用的示例。這讓你對正在閱讀的內容充滿信心,並可以使用不同的選項來檢查結果。隨意修改任何示例並在線執行它。
var message:string = "Hello World" console.log(message)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var message = "Hello World"; console.log(message);
在本章中,我們將討論如何在 Windows 平臺上安裝 TypeScript。我們還將解釋如何安裝 Brackets IDE。
你可以使用 www.typescriptlang.org/Playground 上的 TypeScript 線上測試你的指令碼。線上編輯器顯示編譯器生成的相應 JavaScript 程式碼。

你可以使用Playground嘗試以下示例。
var num:number = 12 console.log(num)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var num = 12; console.log(num);
上面程式的輸出如下:
12
本地環境搭建
TypeScript 是一種開源技術。它可以在任何瀏覽器、任何主機和任何作業系統上執行。你需要以下工具來編寫和測試 TypeScript 程式:
文字編輯器
文字編輯器幫助你編寫原始碼。一些編輯器的例子包括 Windows 記事本、Notepad++、Emacs、vim 或 vi 等。使用的編輯器可能因作業系統而異。
原始檔通常使用副檔名.ts命名。
TypeScript 編譯器
TypeScript 編譯器本身就是一個.ts檔案,編譯成 JavaScript (.js) 檔案。TSC(TypeScript 編譯器)是一個源到源編譯器(轉譯器)。

TSC 生成傳遞給它的.ts檔案的 JavaScript 版本。換句話說,TSC 從作為輸入給它的 TypeScript 檔案生成等效的 JavaScript 原始碼。這個過程稱為轉譯。
但是,編譯器會拒絕任何傳遞給它的原始 JavaScript 檔案。編譯器只處理.ts或.d.ts檔案。
安裝 Node.js
Node.js 是一個開源的、跨平臺的伺服器端 JavaScript 執行時環境。Node.js 可以在沒有瀏覽器支援的情況下執行 JavaScript。它使用 Google V8 JavaScript 引擎來執行程式碼。你可以下載 Node.js 原始碼或適用於你平臺的預構建安裝程式。Node 可在此處獲取:https://nodejs.org/en/download
在 Windows 上安裝
按照以下步驟在 Windows 環境中安裝 Node.js。
步驟 1 - 下載並執行 Node 的 .msi 安裝程式。

步驟 2 - 要驗證安裝是否成功,請在終端視窗中輸入命令node –v。

步驟 3 - 在終端視窗中輸入以下命令以安裝 TypeScript。
npm install -g typescript

在 Mac OS X 上安裝
要在 Mac OS X 上安裝 node.js,你可以下載一個預編譯的二進位制包,這使得安裝非常容易。訪問http://nodejs.org/ 並單擊安裝按鈕下載最新包。

按照安裝嚮導安裝.dmg中的包,這將同時安裝 node 和npm。npm 是 Node 包管理器,它有助於安裝 node.js 的附加包。

在 Linux 上安裝
在安裝 Node.js 和 NPM 之前,您需要安裝一些依賴項。
Ruby 和 GCC。您需要 Ruby 1.8.6 或更高版本以及 GCC 4.2 或更高版本。
Homebrew。Homebrew 是最初為 Mac 設計的包管理器,但它已被移植到 Linux 上作為 Linuxbrew。您可以在 http://brew.sh/ 瞭解更多關於 Homebrew 的資訊,以及在 http://brew.sh/linuxbrew 瞭解更多關於 Linuxbrew 的資訊。
安裝這些依賴項後,您可以使用終端上的以下命令安裝 Node.js:
brew install node.
IDE 支援
TypeScript 可以在許多開發環境中構建,例如 Visual Studio、Sublime Text 2、WebStorm/PHPStorm、Eclipse、Brackets 等。這裡將討論 Visual Studio Code 和 Brackets IDE。此處使用的開發環境是 Visual Studio Code(Windows 平臺)。
Visual Studio Code
這是一個來自 Visual Studio 的開源 IDE。它適用於 Mac OS X、Linux 和 Windows 平臺。VScode 可在以下網址獲取:https://vscode.com.tw/
在 Windows 上安裝
步驟 1 − 下載適用於 Windows 的 Visual Studio Code。

步驟 2 − 雙擊 VSCodeSetup.exe 以啟動安裝過程。這隻需要一分鐘。

步驟 3 − 下面是 IDE 的螢幕截圖。

步驟 4 − 您可以透過右鍵單擊檔案 → 在命令提示符中開啟 來直接轉到檔案的路徑。類似地,“在資源管理器中顯示”選項會在檔案資源管理器中顯示檔案。

在 Mac OS X 上安裝
Visual Studio Code 的 Mac OS X 特定安裝指南可在以下網址找到:
https://vscode.com.tw/Docs/editor/setup
在 Linux 上安裝
Visual Studio Code 的 Linux 特定安裝指南可在以下網址找到:
https://vscode.com.tw/Docs/editor/setup
Brackets
Brackets 是一個免費的開源 Web 開發編輯器,由 Adobe Systems 建立。它適用於 Linux、Windows 和 Mac OS X。Brackets 可在 http://brackets.io/ 獲取。

Brackets 的 TypeScript 擴充套件
Brackets 支援透過擴充套件管理器新增額外功能的擴充套件。以下步驟說明了如何使用擴充套件管理器安裝 TypeScript 擴充套件。
安裝後,單擊編輯器右側的擴充套件管理器圖示
。在搜尋框中輸入 typescript。
安裝 Brackets TSLint 和 Brackets TypeScript 外掛。

您可以透過新增另一個擴充套件 Brackets Shell,在 Brackets 本身中執行 DOS 提示符/shell。

安裝後,您會在編輯器右側找到 shell 圖示 。單擊該圖示後,您將看到如下所示的 shell 視窗:

注意 − TypeScript 也可作為 Visual Studio 2012 和 2013 環境的外掛使用 (https://www.typescriptlang.org/#Download).VS 2015 及更高版本預設包含 TypeScript 外掛。
現在,一切就緒!!!
TypeScript - 基本語法
語法定義了一套編寫程式的規則。每種語言規範都定義了自己的語法。TypeScript 程式由以下部分組成:
- 模組
- 函式
- 變數
- 語句和表示式
- 註釋
您的第一個 TypeScript 程式碼
讓我們從傳統的“Hello World”示例開始:
var message:string = "Hello World" console.log(message)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var message = "Hello World"; console.log(message);
第 1 行宣告一個名為 message 的變數。變數是程式中儲存值的機制。
第 2 行將變數的值列印到提示符。這裡,console 指的是終端視窗。log() 函式用於在螢幕上顯示文字。
編譯和執行 TypeScript 程式
讓我們看看如何使用 Visual Studio Code 編譯和執行 TypeScript 程式。請按照以下步驟操作:
步驟 1 − 使用 .ts 副檔名儲存檔案。我們將檔案儲存為 Test.ts。如果程式碼中存在任何錯誤,程式碼編輯器會在您儲存時標記這些錯誤。
步驟 2 − 右鍵單擊 VS Code 的“資源管理器”窗格中“工作檔案”選項下的 TypeScript 檔案。選擇“在命令提示符中開啟”選項。

步驟 3 − 要編譯檔案,請在終端視窗中使用以下命令。
tsc Test.ts
步驟 4 − 檔案編譯為 Test.js。要執行編寫的程式,請在終端中輸入以下內容。
node Test.js
編譯器標誌
編譯器標誌使您能夠在編譯期間更改編譯器的行為。每個編譯器標誌都公開一個設定,允許您更改編譯器的行為方式。
下表列出了一些與 TSC 編譯器相關的常用標誌。典型的命令列用法使用部分或全部開關。
序號 | 編譯器標誌和說明 |
---|---|
1. | --help 顯示幫助手冊 |
2. | --module 載入外部模組 |
3. | --target 設定目標 ECMA 版本 |
4. | --declaration 生成額外的 .d.ts 檔案 |
5. | --removeComments 從輸出檔案中刪除所有註釋 |
6. | --out 將多個檔案編譯到單個輸出檔案中 |
7. | --sourcemap 生成源對映 (.map) 檔案 |
8. | --module noImplicitAny 禁止編譯器推斷 any 型別 |
9. | --watch 監視檔案更改並動態重新編譯它們 |
注意 − 可以一次編譯多個檔案。
tsc file1.ts, file2.ts, file3.ts
TypeScript 中的識別符號
識別符號是賦予程式中元素(如變數、函式等)的名稱。識別符號的規則如下:
識別符號可以包含字元和數字。但是,識別符號不能以數字開頭。
識別符號不能包含特殊符號,下劃線 (_) 或美元符號 ($) 除外。
識別符號不能是關鍵字。
它們必須是唯一的。
識別符號區分大小寫。
識別符號不能包含空格。
下表列出了一些有效和無效識別符號的示例:
有效識別符號 | 無效識別符號 |
---|---|
firstName | Var |
first_name | first name |
num1 | first-name |
$result | 1number |
TypeScript ─ 關鍵字
關鍵字在語言環境中具有特殊含義。下表列出了 TypeScript 中的一些關鍵字。
break | as | any | switch |
case | if | throw | else |
var | number | string | get |
module | type | instanceof | typeof |
public | private | enum | export |
finally | for | while | void |
null | super | this | new |
in | return | true | false |
any | extends | static | let |
package | implements | interface | function |
new | try | yield | const |
continue | do | catch |
空格和換行符
TypeScript 忽略程式中出現的空格、製表符和換行符。您可以在程式中自由使用空格、製表符和換行符,並且您可以自由地以整潔一致的方式格式化和縮排程式,使程式碼易於閱讀和理解。
TypeScript 區分大小寫
TypeScript 區分大小寫。這意味著 TypeScript 區分大寫和小寫字元。
分號是可選的
每行指令稱為語句。TypeScript 中的分號是可選的。
示例
console.log("hello world") console.log("We are learning TypeScript")
單行可以包含多個語句。但是,這些語句必須用分號隔開。
TypeScript 中的註釋
註釋是提高程式可讀性的一種方法。註釋可用於包含有關程式的其他資訊,例如程式碼作者、關於函式/結構的提示等。編譯器會忽略註釋。
TypeScript 支援以下型別的註釋:
單行註釋 ( // ) − // 和行尾之間的任何文字都被視為註釋
多行註釋 (/* */) − 這些註釋可以跨越多行。
示例
//this is single line comment /* This is a Multi-line comment */
TypeScript 和麵向物件
TypeScript 是面向物件的 JavaScript。面向物件是一種軟體開發範例,遵循現實世界的建模。面向物件將程式視為物件的集合,這些物件透過稱為方法的機制相互通訊。TypeScript 也支援這些面向物件的元件。
物件 − 物件是任何實體的即時表示。根據 Grady Brooch 的說法,每個物件都必須具有三個特徵:
狀態 − 由物件的屬性描述
行為 − 描述物件的行為方式
標識 − 一個唯一值,用於區分物件與一組類似的物件。
類 − 就 OOP 而言,類是建立物件的藍圖。類封裝了物件的資料。
方法 − 方法促進物件之間的通訊。
示例:TypeScript 和麵向物件
class Greeting { greet():void { console.log("Hello World!!!") } } var obj = new Greeting(); obj.greet();
上面的示例定義了一個類 Greeting。該類有一個方法 greet()。該方法在終端上列印字串“Hello World”。new 關鍵字建立類的物件 (obj)。該物件呼叫方法 greet()。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Greeting = (function () { function Greeting() { } Greeting.prototype.greet = function () { console.log("Hello World!!!"); }; return Greeting; }()); var obj = new Greeting(); obj.greet()
上面程式的輸出如下:
Hello World!!!
TypeScript - 型別
型別系統表示語言支援的不同型別的值。型別系統會在程式儲存或操作值之前檢查其有效性。這確保程式碼按預期執行。型別系統還可以提供更豐富的程式碼提示和自動文件。
TypeScript 提供資料型別作為其可選型別系統的一部分。資料型別分類如下:

Any 型別
any 資料型別是 TypeScript 中所有型別的超型別。它表示動態型別。使用any 型別等同於選擇退出變數的型別檢查。
內建型別
下表說明了 TypeScript 中所有內建型別:
資料型別 | 關鍵字 | 說明 |
---|---|---|
Number | number | 雙精度 64 位浮點數。它可以用來表示整數和小數。 |
String | string | 表示 Unicode 字元序列 |
Boolean | boolean | 表示邏輯值,true 和 false |
Void | void | 用於函式返回型別以表示非返回函式 |
Null | null | 表示物件值的故意缺失。 |
Undefined | undefined | 表示賦予所有未初始化變數的值 |
注意 − TypeScript 和 JavaScript 中沒有整數型別。
Null 和 undefined ─ 它們一樣嗎?
null 和 undefined 資料型別經常是混淆的來源。null 和 undefined 不能用於引用變數的資料型別。它們只能作為值分配給變數。
但是,null 和 undefined 是不同的。用 undefined 初始化的變量表示該變數沒有值或物件分配給它,而 null 表示該變數已被設定為值為 undefined 的物件。
使用者自定義型別
使用者自定義型別包括列舉 (enums)、類、介面、陣列和元組。這些將在後面的章節中詳細討論。
TypeScript - 變數
根據定義,變數是“記憶體中命名的空間”,用於儲存值。換句話說,它充當程式中值的容器。TypeScript 變數必須遵循 JavaScript 命名規則:
變數名可以包含字母和數字。
它們不能包含空格和特殊字元,下劃線 (_) 和美元符號 ($) 除外。
變數名不能以數字開頭。
必須在使用變數之前宣告它。使用var關鍵字宣告變數。
TypeScript 中的變數宣告
在 TypeScript 中宣告變數的型別語法是在變數名後包含一個冒號 (:),後跟其型別。就像在 JavaScript 中一樣,我們使用var關鍵字宣告變數。
宣告變數時,您有四個選項:
在一個語句中宣告其型別和值。

宣告其型別但不宣告值。在這種情況下,變數將設定為 undefined。

宣告其值但不宣告型別。變數型別將設定為賦值的資料型別。

既不宣告值也不宣告型別。在這種情況下,變數的資料型別將為 any,並將初始化為 undefined。

下表說明了如上所述的變數宣告的有效語法:
序號 | 變數宣告語法和說明 |
---|---|
1. | var name:string = ”mary” 該變數儲存字串型別的值 |
2. | var name:string; 該變數是一個字串變數。預設情況下,變數的值設定為 undefined |
3. | var name = ”mary” 變數的型別是從值的資料型別推斷出來的。這裡,變數的型別為字串 |
4. | var name; 變數的資料型別為 any。預設情況下,其值設定為 undefined。 |
示例:TypeScript 中的變數
var name:string = "John"; var score1:number = 50; var score2:number = 42.50 var sum = score1 + score2 console.log("name"+name) console.log("first score: "+score1) console.log("second score: "+score2) console.log("sum of the scores: "+sum)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var name = "John"; var score1 = 50; var score2 = 42.50; var sum = score1 + score2; console.log("name" + name); console.log("first score: " + score1); console.log("second score : " + score2); console.log("sum of the scores: " + sum);
上面程式的輸出如下:
name:John first score:50 second score:42.50 sum of the scores:92.50
如果我們嘗試將值賦給與型別不相同的變數,TypeScript 編譯器將生成錯誤。因此,TypeScript 遵循強型別。強型別語法確保賦值運算子 (=) 兩側指定的型別相同。這就是以下程式碼會導致編譯錯誤的原因:
var num:number = "hello" // will result in a compilation error
TypeScript 中的型別斷言
TypeScript 允許將變數從一種型別更改為另一種型別。TypeScript 將此過程稱為型別斷言。語法是在 < > 符號之間放置目標型別,並將其放在變數或表示式之前。以下示例解釋了這個概念:
示例
var str = '1' var str2:number = <number> <any> str //str is now of type number console.log(typeof(str2))
如果將滑鼠指標懸停在 Visual Studio Code 中的型別斷言語句上,它將顯示變數資料型別的變化。基本上,如果 S 是 T 的子型別或 T 是 S 的子型別,它允許從型別 S 到 T 的斷言成功。
之所以不稱其為“型別轉換”,是因為轉換通常意味著某種執行時支援,而“型別斷言”純粹是編譯時構造,以及向編譯器提供提示以說明您希望如何分析程式碼的一種方式。
編譯後,它將生成以下 JavaScript 程式碼。
"use strict"; var str = '1'; var str2 = str; //str is now of type number console.log(typeof (str2));
它將產生以下輸出:
string
TypeScript 中的型別推斷
鑑於 TypeScript 是強型別的,此功能是可選的。TypeScript 也鼓勵變數的動態型別。這意味著 TypeScript 鼓勵在沒有型別的情況下宣告變數。在這種情況下,編譯器將根據分配給它的值來確定變數的型別。TypeScript 將找到程式碼中變數的第一次使用,確定其最初設定的型別,然後在此程式碼塊的其餘部分中假設此變數的相同型別。
以下程式碼片段解釋了相同的內容:
示例:型別推斷
var num = 2; // data type inferred as number console.log("value of num "+num); num = "12"; console.log(num);
在上面的程式碼片段中:
程式碼宣告一個變數並將其值設定為 2。請注意,變數宣告沒有指定資料型別。因此,程式使用型別推斷來確定變數的資料型別,即它為變數設定的第一個值的型別。在這種情況下,num 設定為 number 型別。
當代碼嘗試將變數的值設定為字串時。編譯器會丟擲錯誤,因為變數的型別已設定為 number。
它將產生以下輸出:
error TS2011: Cannot convert 'string' to 'number'.
TypeScript 變數作用域
變數的作用域指定變數的定義位置。程式中變數的可用性由其作用域決定。TypeScript 變數可以具有以下作用域:
全域性作用域- 全域性變數在程式設計結構之外宣告。可以從程式碼中的任何位置訪問這些變數。
類作用域- 這些變數也稱為欄位。欄位或類變數在類內但方法之外宣告。可以使用類的物件訪問這些變數。欄位也可以是靜態的。可以使用類名訪問靜態欄位。
區域性作用域- 區域性變數顧名思義是在方法、迴圈等結構中宣告的。區域性變數只能在其宣告的結構內訪問。
以下示例說明了 TypeScript 中的變數作用域。
示例:變數作用域
var global_num = 12 //global variable class Numbers { num_val = 13; //class variable static sval = 10; //static field storeNum():void { var local_num = 14; //local variable } } console.log("Global num: "+global_num) console.log(Numbers.sval) //static variable var obj = new Numbers(); console.log("Global num: "+obj.num_val)
在轉譯時,將生成以下 JavaScript 程式碼:
var global_num = 12; //global variable var Numbers = (function () { function Numbers() { this.num_val = 13; //class variable } Numbers.prototype.storeNum = function () { var local_num = 14; //local variable }; Numbers.sval = 10; //static field return Numbers; }()); console.log("Global num: " + global_num); console.log(Numbers.sval); //static variable var obj = new Numbers(); console.log("Global num: " + obj.num_val);
它將產生以下輸出:
Global num: 12 10 Global num: 13
如果嘗試在方法外部訪問區域性變數,則會導致編譯錯誤。
error TS2095: Could not find symbol 'local_num'.
TypeScript - 運算子
什麼是運算子?
運算子定義將在資料上執行的某些函式。運算子作用於的資料稱為運算元。考慮以下表達式:
7 + 5 = 12
這裡,值 7、5 和 12 是運算元,而 + 和 = 是運算子。
TypeScript 中的主要運算子可以分類為:
- 算術運算子
- 邏輯運算子
- 關係運算符
- 位運算子
- 賦值運算子
- 三元/條件運算子
- 字串運算子
- 型別運算子
算術運算子
假設變數 a 和 b 中的值分別為 10 和 5。
運算子 | 說明 | 示例 |
---|---|---|
+ (加法) | 返回運算元的和 | a + b 為 15 |
- (減法) | 返回值的差 | a - b 為 5 |
* (乘法) | 返回值的積 | a * b 為 50 |
/ (除法) | 執行除法運算並返回商 | a / b 為 2 |
% (模) | 執行除法運算並返回餘數 | a % b 為 0 |
++ (增量) | 將變數的值增加一 | a++ 為 11 |
-- (減量) | 將變數的值減少一 | a-- 為 9 |
關係運算符
關係運算符測試或定義兩個實體之間的關係型別。關係運算符返回布林值,即 true/false。
假設 A 的值為 10,B 的值為 20。
運算子 | 說明 | 示例 |
---|---|---|
> | 大於 | (A > B) 為 False |
< | 小於 | (A < B) 為 True |
>= | 大於或等於 | (A >= B) 為 False |
<= | 小於或等於 | (A <= B) 為 True |
== | 相等 | (A == B) 為 false |
!= | 不相等 | (A != B) 為 True |
邏輯運算子
邏輯運算子用於組合兩個或多個條件。邏輯運算子也返回布林值。假設變數 A 的值為 10,B 的值為 20。
運算子 | 說明 | 示例 |
---|---|---|
&& (與) | 只有當所有指定的表示式都返回 true 時,運算子才返回 true | (A > 10 && B > 10) 為 False |
|| (或) | 如果至少一個指定的表示式返回 true,則運算子返回 true | (A > 10 || B > 10) 為 True |
! (非) | 運算子返回表示式的結果的反義。例如:! (>5) 返回 false | !(A > 10) 為 True |
位運算子
假設變數 A = 2,B = 3
運算子 | 說明 | 示例 |
---|---|---|
& (按位與) | 它對每個整數引數的每一位執行布林與運算。 | (A & B) 為 2 |
| (按位或) | 它對每個整數引數的每一位執行布林或運算。 | (A | B) 為 3 |
^ (按位異或) | 它對每個整數引數的每一位執行布林異或運算。異或意味著運算元一為真或運算元二為真,但兩者不能同時為真。 | (A ^ B) 為 1 |
~ (按位非) | 它是一個一元運算子,透過反轉運算元中的所有位來操作。 | (~B) 為 -4 |
<< (左移) | 它將第一個運算元中的所有位向左移動第二個運算元中指定的位數。新位用零填充。將值左移一位相當於將其乘以 2,左移兩位相當於將其乘以 4,依此類推。 | (A << 1) 為 4 |
> (右移) | 二進位制右移運算子。左運算元的值向右移動右運算元指定的位數。 | (A >> 1) 為 1 |
>> (帶零的右移) | 此運算子與 >> 運算子類似,只是左側移入的位始終為零。 | (A >>> 1) 為 1 |
賦值運算子
運算子 | 說明 | 示例 |
---|---|---|
= (簡單賦值) | 將值從右側運算元賦值給左側運算元 | C = A + B 將 A + B 的值賦給 C |
+= (加法賦值) | 它將右運算元新增到左運算元,並將結果賦給左運算元。 | C += A 等效於 C = C + A |
-= (減法賦值) | 它從左運算元中減去右運算元,並將結果賦給左運算元。 | C -= A 等效於 C = C - A |
*= (乘法賦值) | 它將右運算元乘以左運算元,並將結果賦給左運算元。 | C *= A 等效於 C = C * A |
/= (除法賦值) | 它將左運算元除以右運算元,並將結果賦給左運算元。 |
注意- 位運算子也適用相同的邏輯,因此它們將變為 <<=、>>=、>>>=、&=、|= 和 ^=。
其他運算子
否定運算子 (-)
更改值的符號。讓我們舉個例子。
var x:number = 4 var y = -x; console.log("value of x: ",x); //outputs 4 console.log("value of y: ",y); //outputs -4
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var x = 4; var y = -x; console.log("value of x: ", x); //outputs 4 console.log("value of y: ", y); //outputs -4
它將產生以下輸出:
value of x: 4 value of y: -4
字串運算子:連線運算子 (+)
當“+”運算子應用於字串時,它會將第二個字串附加到第一個字串的後面。下面的例子可以幫助我們理解這個概念。
var msg:string = "hello"+"world" console.log(msg)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var msg = "hello" + "world"; console.log(msg);
它將產生以下輸出:
helloworld
字串連線操作不會在字串之間新增空格。多個字串可以在單個語句中連線。
條件運算子 (?)
此運算子用於表示條件表示式。條件運算子有時也稱為三元運算子。語法如下所示:
Test ? expr1 : expr2
Test − 指的是條件表示式
expr1 − 如果條件為真則返回的值
expr2 − 如果條件為假則返回的值
讓我們來看下面的程式碼:
var num:number = -2 var result = num > 0 ?"positive":"non-positive" console.log(result)
第 2 行檢查變數num的值是否大於零。如果num設定為大於零的值,則返回字串“positive”,否則返回字串“non-positive”。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var num = -2; var result = num > 0 ? "positive" : "non-positive"; console.log(result);
上面的程式碼片段將產生以下輸出:
non-positive
型別運算子
typeof 運算子
它是一個一元運算子。此運算子返回運算元的資料型別。請看下面的例子:
var num = 12 console.log(typeof num); //output: number
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var num = 12; console.log(typeof num); //output: number
它將產生以下輸出:
number
instanceof
此運算子可以用來測試一個物件是否屬於指定的型別。instanceof 運算子的用法在類這一章中討論。
TypeScript - 決策
決策結構要求程式設計師指定一個或多個條件供程式評估或測試,以及在確定條件為真時要執行的語句,以及可選地在確定條件為假時要執行的其他語句。
下面顯示的是大多數程式語言中典型的決策結構的一般形式:

決策結構在執行指令之前會評估條件。TypeScript 中的決策結構分類如下:
序號 | 語句和說明 |
---|---|
1. | if 語句
一個 'if' 語句由一個布林表示式後跟一個或多個語句組成。 |
2. | if...else 語句
一個 'if' 語句後面可以跟一個可選的 'else' 語句,當布林表示式為假時執行。 |
3. | else…if 和巢狀 if 語句
你可以在另一個 'if' 或 'else if' 語句中使用一個 'if' 或 'else if' 語句。 |
4. | switch 語句
一個 'switch' 語句允許一個變數針對一個值的列表進行測試。 |
TypeScript - 迴圈
你可能會遇到這種情況,需要多次執行一段程式碼。通常情況下,語句是順序執行的:函式中的第一個語句首先執行,然後是第二個,依此類推。
程式語言提供各種控制結構,允許更復雜的執行路徑。
迴圈語句允許我們多次執行一個語句或一組語句。下面是在大多數程式語言中迴圈語句的一般形式。

TypeScript 提供不同型別的迴圈來處理迴圈需求。下圖說明了迴圈的分類:

確定迴圈
迭代次數確定/固定的迴圈稱為確定迴圈。for 迴圈是確定迴圈的一種實現。
序號 | 迴圈和說明 |
---|---|
1. | for 迴圈
for 迴圈是確定迴圈的一種實現。 |
不確定迴圈
當迴圈的迭代次數不確定或未知時,使用不確定迴圈。
不確定迴圈可以使用:
序號 | 迴圈和說明 |
---|---|
1. | while 迴圈
while 迴圈每次指定的條件計算結果為真時都執行指令。 |
2. | do…while
do…while 迴圈類似於 while 迴圈,只是 do...while 迴圈在第一次執行迴圈時不評估條件。 |
示例:while 與 do..while
var n:number = 5 while(n > 5) { console.log("Entered while") } do { console.log("Entered do…while") } while(n>5)
此示例最初聲明瞭一個 while 迴圈。只有當傳遞給 while 的表示式計算結果為真時,才會進入迴圈。在此示例中,n 的值不大於零,因此表示式返回 false,並且迴圈被跳過。
另一方面,do…while 迴圈會執行一次語句。這是因為初始迭代不考慮布林表示式。但是,對於後續迭代,while 會檢查條件並將控制權移出迴圈。
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var n = 5; while (n > 5) { console.log("Entered while"); } do { console.log("Entered do…while"); } while (n > 5);
上面的程式碼將產生以下輸出:
Entered do…while
break 語句
break 語句用於將控制權移出結構。在迴圈中使用break會導致程式退出迴圈。其語法如下:
語法
break
流程圖

示例
現在,讓我們來看下面的示例程式碼:
var i:number = 1 while(i<=10) { if (i % 5 == 0) { console.log ("The first multiple of 5 between 1 and 10 is : "+i) break //exit the loop if the first multiple is found } i++ } //outputs 5 and exits the loop
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var i = 1; while (i <= 10) { if (i % 5 == 0) { console.log("The first multiple of 5 between 1 and 10 is : " + i); break; //exit the loop if the first multiple is found } i++; } //outputs 5 and exits the loop
它將產生以下輸出:
The first multiple of 5 between 1 and 10 is : 5
continue 語句
continue 語句跳過當前迭代中的後續語句,並將控制權返回到迴圈的開頭。與 break 語句不同,continue 不會退出迴圈。它終止當前迭代並開始後續迭代。
語法
continue
流程圖

示例
continue 語句的示例如下:
var num:number = 0 var count:number = 0; for(num=0;num<=20;num++) { if (num % 2==0) { continue } count++ } console.log (" The count of odd values between 0 and 20 is: "+count) //outputs 10
上面的例子顯示了 0 到 20 之間偶數的數量。如果數字是偶數,迴圈會退出當前迭代。這是使用continue語句實現的。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var num = 0; var count = 0; for (num = 0; num <= 20; num++) { if (num % 2 == 0) { continue; } count++; } console.log(" The count of odd values between 0 and 20 is: " + count); //outputs 10
輸出
The count of odd values between 0 and 20 is: 10
無限迴圈
無限迴圈是一個無限執行的迴圈。for迴圈和while迴圈可以用來建立一個無限迴圈。
語法:使用 for 迴圈建立無限迴圈
for(;;) { //statements }
示例:使用 for 迴圈建立無限迴圈
for(;;) { console.log(“This is an endless loop”) }
語法:使用 while 迴圈建立無限迴圈
while(true) { //statements }
示例:使用 while 迴圈建立無限迴圈
while(true) { console.log(“This is an endless loop”) }
TypeScript - 函式
函式是可讀、可維護和可重用程式碼的構建塊。函式是一組執行特定任務的語句。函式將程式組織成邏輯程式碼塊。一旦定義,就可以呼叫函式來訪問程式碼。這使得程式碼可重用。此外,函式使程式程式碼易於閱讀和維護。
函式宣告告訴編譯器函式的名稱、返回型別和引數。函式定義提供了函式的實際主體。
序號 | 函式和說明 |
---|---|
1. | 定義函式
函式定義指定了如何執行特定任務。 |
2. | 呼叫函式
必須呼叫函式才能執行它。 |
3. | 返回函式
函式也可以將值和控制權一起返回給呼叫者。 |
4. | 引數化函式
引數是將值傳遞給函式的一種機制。 |
可選引數
當不需要強制傳遞引數來執行函式時,可以使用可選引數。可以透過在其名稱後附加問號來將引數標記為可選。可選引數應設定為函式中的最後一個引數。宣告帶可選引數的函式的語法如下:
function function_name (param1[:type], param2[:type], param3[:type])
示例:可選引數
function disp_details(id:number,name:string,mail_id?:string) { console.log("ID:", id); console.log("Name",name); if(mail_id!=undefined) console.log("Email Id",mail_id); } disp_details(123,"John"); disp_details(111,"mary","mary@xyz.com");
上面的例子聲明瞭一個引數化函式。這裡,第三個引數,即 mail_id 是一個可選引數。
如果在函式呼叫期間未傳遞可選引數的值,則引數的值將設定為 undefined。
該函式僅當引數傳遞值時才打印 mail_id 的值。
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 function disp_details(id, name, mail_id) { console.log("ID:", id); console.log("Name", name); if (mail_id != undefined) console.log("Email Id", mail_id); } disp_details(123, "John"); disp_details(111, "mary", "mary@xyz.com");
上面的程式碼將產生以下輸出:
ID:123 Name John ID: 111 Name mary Email Id mary@xyz.com
剩餘引數
剩餘引數類似於 Java 中的可變引數。剩餘引數不限制可以傳遞給函式的值的數量。但是,傳遞的值必須全部為相同型別。換句話說,剩餘引數充當相同型別多個引數的佔位符。
要宣告剩餘引數,引數名稱前面要加上三個點。任何非剩餘引數都應放在剩餘引數之前。
示例:剩餘引數
function addNumbers(...nums:number[]) { var i; var sum:number = 0; for(i = 0;i<nums.length;i++) { sum = sum + nums[i]; } console.log("sum of the numbers",sum) } addNumbers(1,2,3) addNumbers(10,10,10,10,10)
函式 addNumbers() 宣告接受一個剩餘引數nums。剩餘引數的資料型別必須設定為陣列。此外,函式最多隻能有一個剩餘引數。
該函式被呼叫兩次,分別傳遞三個和六個值。
for 迴圈遍歷傳遞給函式的引數列表並計算它們的總和。
編譯後,它將生成以下 JavaScript 程式碼:
function addNumbers() { var nums = []; for (var _i = 0; _i < arguments.length; _i++) { nums[_i - 0] = arguments[_i]; } var i; var sum = 0; for (i = 0; i < nums.length; i++) { sum = sum + nums[i]; } console.log("sum of the numbers", sum); } addNumbers(1, 2, 3); addNumbers(10, 10, 10, 10, 10);
上述程式碼的輸出如下:
sum of numbers 6 sum of numbers 50
預設引數
函式引數也可以分配預設值。但是,這些引數也可以顯式地傳遞值。
語法
function function_name(param1[:type],param2[:type] = default_value) { }
注意 - 引數不能同時宣告為可選和預設。
示例:預設引數
function calculate_discount(price:number,rate:number = 0.50) { var discount = price * rate; console.log("Discount Amount: ",discount); } calculate_discount(1000) calculate_discount(1000,0.30)
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 function calculate_discount(price, rate) { if (rate === void 0) { rate = 0.50; } var discount = price * rate; console.log("Discount Amount: ", discount); } calculate_discount(1000); calculate_discount(1000, 0.30);
其輸出如下:
Discount amount : 500 Discount amount : 300
此示例聲明瞭函式calculate_discount。該函式有兩個引數 - price 和 rate。
引數rate的值預設為0.50。
程式呼叫該函式,只傳遞引數 price 的值。這裡,rate的值為0.50(預設)
呼叫相同的函式,但是有兩個引數。rate的預設值被覆蓋,並設定為顯式傳遞的值。
匿名函式
不繫結到識別符號(函式名)的函式稱為匿名函式。這些函式在執行時動態宣告。匿名函式可以接受輸入並返回輸出,就像標準函式一樣。匿名函式在其初始建立後通常是不可訪問的。
變數可以賦值為匿名函式。這樣的表示式稱為函式表示式。
語法
var res = function( [arguments] ) { ... }
示例─一個簡單的匿名函式
var msg = function() { return "hello world"; } console.log(msg())
編譯後,它將在 JavaScript 中生成相同的程式碼。
它將產生以下輸出:
hello world
示例─帶引數的匿名函式
var res = function(a:number,b:number) { return a*b; }; console.log(res(12,2))
匿名函式返回傳遞給它的值的乘積。
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var res = function (a, b) { return a * b; }; console.log(res(12, 2));
上述程式碼的輸出如下:
24
函式表示式和函式宣告─它們是同義詞嗎?
函式表示式和函式宣告不是同義詞。與函式表示式不同,函式宣告由函式名稱繫結。
兩者之間的根本區別在於,函式宣告在其執行之前被解析。另一方面,函式表示式只有在指令碼引擎在執行過程中遇到它時才被解析。
當 JavaScript 解析器在主程式碼流中看到一個函式時,它假定為函式宣告 (Function Declaration)。當函式作為語句的一部分出現時,它就是一個函式表示式 (Function Expression)。
函式構造器 (The Function Constructor)
TypeScript 也支援使用名為 Function() 的內建 JavaScript 構造器來定義函式。
語法
var res = new Function( [arguments] ) { ... }.
示例
var myFunction = new Function("a", "b", "return a * b"); var x = myFunction(4, 3); console.log(x);
new Function() 是對構造器的呼叫,它依次建立一個並返回函式引用。
編譯後,它將在 JavaScript 中生成相同的程式碼。
上述示例程式碼的輸出如下:
12
遞迴和 TypeScript 函式 (Recursion and TypeScript Functions)
遞迴是一種透過函式反覆呼叫自身直到得到結果來迭代操作的技術。當需要在迴圈內用不同的引數重複呼叫同一個函式時,遞迴最為適用。
示例 - 遞迴 (Example – Recursion)
function factorial(number) { if (number <= 0) { // termination case return 1; } else { return (number * factorial(number - 1)); // function invokes itself } }; console.log(factorial(6)); // outputs 720
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
720
示例:匿名遞迴函式 (Example: Anonymous Recursive Function)
(function () { var x = "Hello!!"; console.log(x) })() // the function invokes itself using a pair of parentheses ()
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
Hello!!
Lambda 函式 (Lambda Functions)
Lambda 指的是程式設計中的匿名函式。Lambda 函式是一種表示匿名函式的簡潔機制。這些函式也稱為**箭頭函式 (Arrow functions)**。
Lambda 函式 - 結構 (Lambda Function - Anatomy)
Lambda 函式由三個部分組成:
**引數 (Parameters)** - 函式可以選擇性地包含引數
**胖箭頭符號/lambda 符號 (=>)** - 也稱為“goes to”運算子
**語句 (Statements)** - 表示函式的指令集
**提示 (Tip)** - 按照慣例,建議為簡潔和精確的函式宣告使用單個字母引數。
Lambda 表示式 (Lambda Expression)
這是一個指向單行程式碼的匿名函式表示式。其語法如下:
( [param1, parma2,…param n] )=>statement;
示例:Lambda 表示式 (Example: Lambda Expression)
var foo = (x:number)=>10 + x console.log(foo(100)) //outputs 110
程式宣告一個 lambda 表示式函式。該函式返回 10 與傳入引數的和。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var foo = function (x) { return 10 + x; }; console.log(foo(100)); //outputs 110
上述程式碼的輸出如下:
110
Lambda 語句 (Lambda Statement)
Lambda 語句是一個指向程式碼塊的匿名函式宣告。當函式體跨越多行時,使用此語法。其語法如下:
( [param1, parma2,…param n] )=> { //code block }
示例:Lambda 語句 (Example: Lambda statement)
var foo = (x:number)=> { x = 10 + x console.log(x) } foo(100)
函式的引用被返回並存儲在變數**foo**中。
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var foo = function (x) { x = 10 + x; console.log(x); }; foo(100);
上述程式的輸出如下:
110
語法變體 (Syntactic Variations)
引數型別推斷 (Parameter type Inference)
不必指定引數的資料型別。在這種情況下,引數的資料型別為 any。讓我們看一下下面的程式碼片段:
var func = (x)=> { if(typeof x=="number") { console.log(x+" is numeric") } else if(typeof x=="string") { console.log(x+" is a string") } } func(12) func("Tom")
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var func = function (x) { if (typeof x == "number") { console.log(x + " is numeric"); } else if (typeof x == "string") { console.log(x + " is a string"); } }; func(12); func("Tom");
其輸出如下:
12 is numeric Tom is a string
單個引數的可選圓括號 (Optional parentheses for a single parameter)
var display = x=> { console.log("The function got "+x) } display(12)
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var display = function (x) { console.log("The function got " + x); }; display(12);
其輸出如下:
The function got 12
單個語句的可選大括號,無引數的空圓括號 (Optional braces for a single statement, Empty parentheses for no parameter)
以下示例展示了這兩種語法變體。
var disp =()=> { console.log("Function invoked"); } disp();
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var disp = function () { console.log("Function invoked"); }; disp();
其輸出如下:
Function invoked
函式過載 (Function Overloads)
函式能夠根據提供的輸入以不同的方式執行。換句話說,程式可以有多個同名但實現不同的方法。這種機制稱為函式過載。TypeScript 支援函式過載。
要在 TypeScript 中過載函式,需要按照以下步驟操作:
**步驟 1** - 宣告多個同名但函式簽名不同的函式。函式簽名包括以下內容。
引數的資料型別
function disp(string):void; function disp(number):void;
引數的數量
function disp(n1:number):void; function disp(x:number,y:number):void;
引數的順序
function disp(n1:number,s1:string):void; function disp(s:string,n:number):void;
**注意** - 函式簽名不包括函式的返回型別。
**步驟 2** - 宣告必須後跟函式定義。如果過載期間引數型別不同,則應將引數型別設定為**any**。此外,對於上面解釋的**情況 b**,可以考慮在函式定義期間將一個或多個引數標記為可選。
**步驟 3** - 最後,必須呼叫函式才能使其生效。
示例
現在讓我們看一下下面的示例程式碼:
function disp(s1:string):void; function disp(n1:number,s1:string):void; function disp(x:any,y?:any):void { console.log(x); console.log(y); } disp("abc") disp(1,"xyz");
前兩行描述了函式過載宣告。該函式有兩個過載:
接受單個字串引數的函式。
分別接受兩個型別為數字和字串的值的函式。
第三行定義了函式。引數的資料型別設定為**any**。此外,這裡第二個引數是可選的。
過載函式由最後兩個語句呼叫。
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 function disp(x, y) { console.log(x); console.log(y); } disp("abc"); disp(1, "xyz");
上面的程式碼將產生以下輸出:
abc 1 xyz
TypeScript - 數字
TypeScript 像 JavaScript 一樣支援數值作為 Number 物件。Number 物件將數值字面量轉換為 Number 類的例項。Number 類充當包裝器,並使數值字面量的操作如同它們是物件一樣。
語法
var var_name = new Number(value)
如果將非數值引數作為 Number 建構函式的引數傳遞,則返回 NaN(非數字)。
下表列出了 Number 物件的一組屬性:
序號 | 屬性和描述 (Property & Description) |
---|---|
1. | MAX_VALUE JavaScript 中數字可以具有的最大值 1.7976931348623157E+308。 |
2. | MIN_VALUE JavaScript 中數字可以具有的最小值 5E-324。 |
3. | NaN 等於非數值。 |
4. | NEGATIVE_INFINITY 小於 MIN_VALUE 的值。 |
5. | POSITIVE_INFINITY 大於 MAX_VALUE 的值。 |
6. | prototype Number 物件的靜態屬性。使用 prototype 屬性可以為當前文件中的 Number 物件分配新的屬性和方法。 |
7. | constructor 返回建立此物件例項的函式。預設情況下,這是 Number 物件。 |
示例
console.log("TypeScript Number Properties: "); console.log("Maximum value that a number variable can hold: " + Number.MAX_VALUE); console.log("The least value that a number variable can hold: " + Number.MIN_VALUE); console.log("Value of Negative Infinity: " + Number.NEGATIVE_INFINITY); console.log("Value of Negative Infinity:" + Number.POSITIVE_INFINITY);
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
TypeScript Number Properties: Maximum value that a number variable can hold: 1.7976931348623157e+308 The least value that a number variable can hold: 5e-324 Value of Negative Infinity: -Infinity Value of Negative Infinity:Infinity
示例:NaN (Example: NaN)
var month = 0 if( month<=0 || month >12) { month = Number.NaN console.log("Month is "+ month) } else { console.log("Value Accepted..") }
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
Month is NaN
示例:prototype (Example: prototye)
function employee(id:number,name:string) { this.id = id this.name = name } var emp = new employee(123,"Smith") employee.prototype.email = "smith@abc.com" console.log("Employee 's Id: "+emp.id) console.log("Employee's name: "+emp.name) console.log("Employee's Email ID: "+emp.email)
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 function employee(id, name) { this.id = id; this.name = name; } var emp = new employee(123, "Smith"); employee.prototype.email = "smith@abc.com"; console.log("Employee 's Id: " + emp.id); console.log("Employee's name: " + emp.name); console.log("Employee's Email ID: " + emp.email);
其輸出如下:
Employee’s Id: 123 Emaployee’s name: Smith Employee’s Email ID: smith@abc.com
Number 方法 (Number Methods)
Number 物件僅包含作為每個物件定義一部分的預設方法。一些常用方法列在下面:
序號 | 方法和描述 (Methods & Description) |
---|---|
1. | toExponential()
強制數字以指數表示法顯示,即使數字在 JavaScript 通常使用標準表示法的範圍內。 |
2. | toFixed()
格式化一個數字,使其小數點右邊有特定數量的位數。 |
3. | toLocaleString()
返回當前數字的字串值版本,其格式可能會根據瀏覽器的本地設定而有所不同。 |
4. | toPrecision()
定義要顯示的數字的總位數(包括小數點左邊和右邊的位數)。負精度將丟擲錯誤。 |
5. | toString()
返回數字值的字串表示形式。該函式傳遞基數,這是一個介於 2 和 36 之間的整數,用於指定表示數值的基數。 |
6. | valueOf()
返回數字的原始值。 |
TypeScript - 字串
String 物件允許您使用一系列字元。它使用許多輔助方法來包裝字串原始資料型別。
語法
var var_name = new String(string);
下面列出了 String 物件中可用的方法及其說明:
序號 | 屬性和描述 (Property & Description) |
---|---|
1. | 構造器 (Constructor)
返回建立物件的 String 函式的引用。 |
2. | 長度 (Length)
返回字串的長度。 |
3. | 原型 (Prototype)
prototype 屬性允許您向物件新增屬性和方法。 |
String 方法 (String Methods)
下面列出了 String 物件中可用的方法及其說明:
序號 | 方法和描述 (Method & Description) |
---|---|
1. | charAt()
返回指定索引處的字元。 |
2. | charCodeAt()
返回一個數字,指示給定索引處字元的 Unicode 值。 |
3. | concat()
組合兩個字串的文字並返回一個新字串。 |
4. | indexOf()
返回呼叫 String 物件中指定值的第一次出現的索引,如果未找到則返回 -1。 |
5. | lastIndexOf()
返回呼叫 String 物件中指定值的最後一次出現的索引,如果未找到則返回 -1。 |
6. | localeCompare()
返回一個數字,指示引用字串在排序順序中是在給定字串之前、之後還是與之相同。 |
7. | match() 用於將正則表示式與字串匹配。 |
8. | replace()
用於查詢正則表示式和字串之間的匹配項,並將匹配的子字串替換為新的子字串。 |
9. | search()
執行對正則表示式和指定字串之間匹配項的搜尋。 |
10. | slice()
提取字串的一部分並返回一個新字串。 |
11. | split()
透過將字串分割成子字串,將 String 物件分割成字串陣列。 |
12. | substr()
返回字串中從指定位置開始的指定數量的字元。 |
13. | substring()
返回字串中兩個索引之間的字元。 |
14. | toLocaleLowerCase()
字串中的字元轉換為小寫,同時尊重當前區域設定。 |
15. | toLocaleUpperCase()
字串中的字元轉換為大寫,同時尊重當前區域設定。 |
16. | toLowerCase()
返回轉換為小寫的呼叫字串值。 |
17. | toString()
返回表示指定物件的字串。 |
18. | toUpperCase()
返回轉換為大寫的呼叫字串值。 |
19. | valueOf()
返回指定物件的原始值。 |
TypeScript - 陣列
使用變數儲存值具有以下限制:
變數本質上是標量的。換句話說,變數宣告一次只能包含一個值。這意味著要在程式中儲存 n 個值,需要 n 個變數宣告。因此,當需要儲存大量值時,使用變數是不可行的。
程式中的變數以隨機順序分配記憶體,從而難以按宣告順序檢索/讀取值。
TypeScript 引入了陣列的概念來解決這個問題。陣列是值的同質集合。簡而言之,陣列是相同資料型別值的集合。它是一種使用者定義型別。
陣列的特性 (Features of an Array)
以下是陣列特性的列表:
陣列宣告分配順序記憶體塊。
陣列是靜態的。這意味著一旦初始化,陣列就不能調整大小。
每個記憶體塊代表一個數組元素。
陣列元素由唯一的整數標識,該整數稱為元素的下標/索引。
與變數一樣,陣列也應在使用前宣告。使用 var 關鍵字宣告陣列。
陣列初始化是指填充陣列元素。
陣列元素值可以更新或修改,但不能刪除。
宣告和初始化陣列 (Declaring and Initializing Arrays)
要在 Typescript 中宣告和初始化陣列,請使用以下語法:
語法
var array_name[:datatype]; //declaration array_name = [val1,val2,valn..] //initialization
沒有資料型別的陣列宣告被認為是 any 型別。此類陣列的型別在初始化期間從陣列第一個元素的資料型別推斷。
例如,像這樣的宣告:**var numlist:number[] = [2,4,6,8]** 將建立一個如下所示的陣列:

陣列指標預設指向第一個元素。
**陣列可以在單個語句中宣告和初始化**。其語法如下:
var array_name[:data type] = [val1,val2…valn]
**注意** - [] 對稱為陣列的維度。
訪問陣列元素 (Accessing Array Elements)
陣列名稱後跟下標用於引用陣列元素。其語法如下:
array_name[subscript] = value
示例:簡單陣列 (Example: Simple Array)
var alphas:string[]; alphas = ["1","2","3","4"] console.log(alphas[0]); console.log(alphas[1]);
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var alphas; alphas = ["1", "2", "3", "4"]; console.log(alphas[0]); console.log(alphas[1]);
上述程式碼的輸出如下:
1 2
示例:單語句宣告和初始化 (Example: Single statement declaration and initialization)
var nums:number[] = [1,2,3,3] console.log(nums[0]); console.log(nums[1]); console.log(nums[2]); console.log(nums[3]);
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var nums = [1, 2, 3, 3]; console.log(nums[0]); console.log(nums[1]); console.log(nums[2]); console.log(nums[3]);
其輸出如下:
1 2 3 3
陣列物件 (Array Object)
也可以使用 Array 物件建立陣列。Array 建構函式可以傳遞。
表示陣列大小的數值,或
逗號分隔值的列表。
以下示例顯示瞭如何使用此方法建立陣列。
示例
var arr_names:number[] = new Array(4) for(var i = 0;i<arr_names.length;i++;) { arr_names[i] = i * 2 console.log(arr_names[i]) }
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var arr_names = new Array(4); for (var i = 0; i < arr_names.length; i++) { arr_names[i] = i * 2; console.log(arr_names[i]); }
其輸出如下:
0 2 4 6
示例:Array 建構函式接受逗號分隔的值 (Example: Array Constructor accepts comma separated values)
var names:string[] = new Array("Mary","Tom","Jack","Jill") for(var i = 0;i<names.length;i++) { console.log(names[i]) }
編譯後,它將生成以下 JavaScript 程式碼:
//Generated by typescript 1.8.10 var names = new Array("Mary", "Tom", "Jack", "Jill"); for (var i = 0; i < names.length; i++) { console.log(names[i]); }
其輸出如下:
Mary Tom Jack Jill
陣列方法 (Array Methods)
下面列出了 Array 物件的方法及其說明。
序號 | 方法和描述 (Method & Description) |
---|---|
1. | concat()
返回一個新陣列,該陣列由該陣列與其他陣列和/或值連線而成。 |
2. | every()
如果陣列中的每個元素都滿足提供的測試函式,則返回 true。 |
3. | filter()
建立一個新陣列,其中包含此陣列中所有使提供的篩選函式返回 true 的元素。 |
4. | forEach()
為陣列中的每個元素呼叫一個函式。 |
5. | indexOf()
返回陣列中等於指定值的元素的第一個(最小)索引,如果未找到則返回 -1。 |
6. | join()
將陣列的所有元素連線成一個字串。 |
7. | lastIndexOf()
返回陣列中等於指定值的元素的最後一個(最大)索引,如果未找到則返回 -1。 |
8. | map()
建立一個新陣列,其中包含對這個陣列中每個元素呼叫提供的函式的結果。 |
9. | pop()
移除陣列的最後一個元素,並返回該元素。 |
10. | push()
向陣列的末尾新增一個或多個元素,並返回陣列的新長度。 |
11. | reduce()
將一個函式同時應用於陣列的兩個值(從左到右),以將其歸約為單個值。 |
12. | reduceRight()
將一個函式同時應用於陣列的兩個值(從右到左),以將其歸約為單個值。 |
13. | reverse()
反轉陣列元素的順序——第一個元素成為最後一個,最後一個元素成為第一個。 |
14. | shift()
移除陣列的第一個元素,並返回該元素。 |
15. | slice()
提取陣列的一部分並返回一個新陣列。 |
16. | some()
如果此陣列中至少有一個元素滿足提供的測試函式,則返回 true。 |
17. | sort()
對陣列的元素進行排序。 |
18. | splice()
向陣列新增和/或從陣列中移除元素。 |
19. | toString()
返回表示陣列及其元素的字串。 |
20. | unshift()
向陣列的開頭新增一個或多個元素,並返回陣列的新長度。 |
陣列解構
指的是分解實體的結構。TypeScript 在陣列上下文中使用時支援解構。
示例
var arr:number[] = [12,13] var[x,y] = arr console.log(x) console.log(y)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var arr = [12, 13]; var x = arr[0], y = arr[1]; console.log(x); console.log(y);
其輸出如下:
12 13
使用 for…in 迴圈遍歷陣列
可以使用for…in迴圈遍歷陣列。
var j:any; var nums:number[] = [1001,1002,1003,1004] for(j in nums) { console.log(nums[j]) }
迴圈執行基於索引的陣列遍歷。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var j; var nums = [1001, 1002, 1003, 1004]; for (j in nums) { console.log(nums[j]); }
上面程式碼的輸出如下:
1001 1002 1003 1004
TypeScript 中的陣列
TypeScript 支援陣列中的以下概念:
序號 | 概念和描述 |
---|---|
1. | 多維陣列
TypeScript 支援多維陣列。多維陣列最簡單的形式是二維陣列。 |
2. | 將陣列傳遞給函式
您可以透過指定陣列的名稱(不帶索引)來將指向陣列的指標傳遞給函式。 |
3. | 從函式返回陣列
允許函式返回陣列 |
TypeScript - 元組
有時,可能需要儲存各種型別值的集合。陣列不能滿足此目的。TypeScript 為我們提供了一種稱為元組的資料型別,有助於實現此目的。
它表示異構值集合。換句話說,元組允許儲存不同型別的多個欄位。元組也可以作為引數傳遞給函式。
語法
var tuple_name = [value1,value2,value3,…value n]
例如
var mytuple = [10,"Hello"];
您也可以在 Typescript 中宣告一個空元組,並選擇稍後對其進行初始化。
var mytuple = []; mytuple[0] = 120 mytuple[1] = 234
訪問元組中的值
元組值分別稱為項。元組是基於索引的。這意味著可以使用其對應的數字索引訪問元組中的項。元組項的索引從零開始,一直延伸到 n-1(其中 n 是元組的大小)。
語法
tuple_name[index]
示例:簡單元組
var mytuple = [10,"Hello"]; //create a tuple console.log(mytuple[0]) console.log(mytuple[1])
在上面的示例中,聲明瞭一個元組mytuple。元組分別包含數值和字串型別的值。
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
10 Hello
示例:空元組
var tup = [] tup[0] = 12 tup[1] = 23 console.log(tup[0]) console.log(tup[1])
編譯後,它將在 JavaScript 中生成相同的程式碼。
其輸出如下:
12 23
元組操作
TypeScript 中的元組支援各種操作,例如推送新項、從元組中移除項等。
示例
var mytuple = [10,"Hello","World","typeScript"]; console.log("Items before push "+mytuple.length) // returns the tuple size mytuple.push(12) // append value to the tuple console.log("Items after push "+mytuple.length) console.log("Items before pop "+mytuple.length) console.log(mytuple.pop()+" popped from the tuple") // removes and returns the last item console.log("Items after pop "+mytuple.length)
push() 將項新增到元組中
pop() 移除並返回元組中的最後一個值
編譯後,它將在 JavaScript 中生成相同的程式碼。
上述程式碼的輸出如下:
Items before push 4 Items after push 5 Items before pop 5 12 popped from the tuple Items after pop 4
更新元組
元組是可變的,這意味著您可以更新或更改元組元素的值。
示例
var mytuple = [10,"Hello","World","typeScript"]; //create a tuple console.log("Tuple value at index 0 "+mytuple[0]) //update a tuple element mytuple[0] = 121 console.log("Tuple value at index 0 changed to "+mytuple[0])
編譯後,它將在 JavaScript 中生成相同的程式碼。
上述程式碼的輸出如下:
Tuple value at index 0 10 Tuple value at index 0 changed to 121
解構元組
解構指的是分解實體的結構。TypeScript 在元組上下文中使用時支援解構。
示例
var a =[10,"hello"] var [b,c] = a console.log( b ) console.log( c )
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var a = [10, "hello"]; var b = a[0], c = a[1]; console.log(b); console.log(c);
其輸出如下:
10 hello
TypeScript - 聯合型別
TypeScript 1.4 使程式能夠組合一種或兩種型別。聯合型別是表達可以是幾種型別之一的值的強大方法。使用管道符號 (|) 組合兩種或多種資料型別來表示聯合型別。換句話說,聯合型別寫成由豎線分隔的型別序列。
語法:聯合字面量
Type1|Type2|Type3
示例:聯合型別變數
var val:string|number val = 12 console.log("numeric value of val "+val) val = "This is a string" console.log("string value of val "+val)
在上面的示例中,變數的型別是聯合型別。這意味著變數可以包含數字或字串作為其值。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var val; val = 12; console.log("numeric value of val " + val); val = "This is a string"; console.log("string value of val " + val);
其輸出如下:
numeric value of val 12 string value of val this is a string
示例:聯合型別和函式引數
function disp(name:string|string[]) { if(typeof name == "string") { console.log(name) } else { var i; for(i = 0;i<name.length;i++) { console.log(name[i]) } } } disp("mark") console.log("Printing names array....") disp(["Mark","Tom","Mary","John"])
函式 disp() 可以接受字串型別或字串陣列型別的引數。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 function disp(name) { if (typeof name == "string") { console.log(name); } else { var i; for (i = 0; i < name.length; i++) { console.log(name[i]); } } } disp("mark"); console.log("Printing names array...."); disp(["Mark", "Tom", "Mary", "John"]);
輸出如下:
Mark Printing names array…. Mark Tom Mary John
聯合型別和陣列
聯合型別也可以應用於陣列、屬性和介面。以下是聯合型別與陣列一起使用的示例。
示例:聯合型別和陣列
var arr:number[]|string[]; var i:number; arr = [1,2,4] console.log("**numeric array**") for(i = 0;i<arr.length;i++) { console.log(arr[i]) } arr = ["Mumbai","Pune","Delhi"] console.log("**string array**") for(i = 0;i<arr.length;i++) { console.log(arr[i]) }
程式宣告一個數組。陣列可以表示數字集合或字串集合。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var arr; var i; arr = [1, 2, 4]; console.log("**numeric array**"); for (i = 0; i < arr.length; i++) { console.log(arr[i]); } arr = ["Mumbai", "Pune", "Delhi"]; console.log("**string array**"); for (i = 0; i < arr.length; i++) { console.log(arr[i]); }
其輸出如下:
**numeric array** 1 2 4 **string array** Mumbai Pune Delhi
TypeScript - 介面
介面是一種語法約定,實體應符合該約定。換句話說,介面定義了任何實體都必須遵守的語法。
介面定義屬性、方法和事件,這些是介面的成員。介面僅包含成員的宣告。派生類負責定義成員。它通常有助於提供派生類將遵循的標準結構。
讓我們考慮一個物件:
var person = { FirstName:"Tom", LastName:"Hanks", sayHi: ()=>{ return "Hi"} };
如果我們考慮物件的簽名,它可能是:
{ FirstName:string, LastName:string, sayHi()=>string }
為了跨物件重用簽名,我們可以將其定義為介面。
宣告介面
interface 關鍵字用於宣告介面。以下是宣告介面的語法:
語法
interface interface_name { }
示例:介面和物件
interface IPerson { firstName:string, lastName:string, sayHi: ()=>string } var customer:IPerson = { firstName:"Tom", lastName:"Hanks", sayHi: ():string =>{return "Hi there"} } console.log("Customer Object ") console.log(customer.firstName) console.log(customer.lastName) console.log(customer.sayHi()) var employee:IPerson = { firstName:"Jim", lastName:"Blakes", sayHi: ():string =>{return "Hello!!!"} } console.log("Employee Object ") console.log(employee.firstName); console.log(employee.lastName);
此示例定義了一個介面。customer 物件的型別為 IPerson。因此,它現在將繫結到物件以根據介面定義所有屬性。
具有以下簽名的另一個物件仍然被視為 IPerson,因為該物件是根據其大小或簽名進行處理的。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var customer = { firstName: "Tom", lastName: "Hanks", sayHi: function () { return "Hi there"; } }; console.log("Customer Object "); console.log(customer.firstName); console.log(customer.lastName); console.log(customer.sayHi()); var employee = { firstName: "Jim", lastName: "Blakes", sayHi: function () { return "Hello!!!"; } }; console.log("Employee Object "); console.log(employee.firstName); console.log(employee.lastName);
上述示例程式碼的輸出如下:
Customer object Tom Hanks Hi there Employee object Jim Blakes Hello!!!
介面不需要轉換為 JavaScript。它只是 TypeScript 的一部分。如果您檢視 TS Playground 工具的螢幕截圖,當您宣告介面時,不會像類一樣發出任何 JavaScript 程式碼。因此,介面對執行時 JavaScript 沒有任何影響。

聯合型別和介面
以下示例顯示了聯合型別和介面的用法:
interface RunOptions { program:string; commandline:string[]|string|(()=>string); } //commandline as string var options:RunOptions = {program:"test1",commandline:"Hello"}; console.log(options.commandline) //commandline as a string array options = {program:"test1",commandline:["Hello","World"]}; console.log(options.commandline[0]); console.log(options.commandline[1]); //commandline as a function expression options = {program:"test1",commandline:()=>{return "**Hello World**";}}; var fn:any = options.commandline; console.log(fn());
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 //commandline as string var options = { program: "test1", commandline: "Hello" }; console.log(options.commandline); //commandline as a string array options = { program: "test1", commandline: ["Hello", "World"] }; console.log(options.commandline[0]); console.log(options.commandline[1]); //commandline as a function expression options = { program: "test1", commandline: function () { return "**Hello World**"; } }; var fn = options.commandline; console.log(fn());
其輸出如下:
Hello Hello World **Hello World**
介面和陣列
介面可以定義陣列使用的鍵的型別以及它包含的條目的型別。索引可以是字串型別或數字型別。
示例
interface namelist { [index:number]:string } var list2:namelist = ["John",1,"Bran"] //Error. 1 is not type string interface ages { [index:string]:number } var agelist:ages; agelist["John"] = 15 // Ok agelist[2] = "nine" // Error
介面和繼承
介面可以被其他介面擴充套件。換句話說,介面可以繼承自其他介面。Typescript 允許介面繼承自多個介面。
使用 extends 關鍵字在介面之間實現繼承。
語法:單介面繼承
Child_interface_name extends super_interface_name
語法:多介面繼承
Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name
示例:簡單介面繼承
interface Person { age:number } interface Musician extends Person { instrument:string } var drummer = <Musician>{}; drummer.age = 27 drummer.instrument = "Drums" console.log("Age: "+drummer.age) console.log("Instrument: "+drummer.instrument)
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var drummer = {}; drummer.age = 27; drummer.instrument = "Drums"; console.log("Age: " + drummer.age); console.log("Instrument: " + drummer.instrument);
其輸出如下:
Age: 27 Instrument: Drums
示例:多介面繼承
interface IParent1 { v1:number } interface IParent2 { v2:number } interface Child extends IParent1, IParent2 { } var Iobj:Child = { v1:12, v2:23} console.log("value 1: "+this.v1+" value 2: "+this.v2)
Iobj 物件的型別為介面 leaf。leaf 介面憑藉繼承現在具有兩個屬性——v1 和 v2。因此,Iobj 物件現在必須包含這些屬性。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Iobj = { v1: 12, v2: 23 }; console.log("value 1: " + this.v1 + " value 2: " + this.v2);
上述程式碼的輸出如下:
value 1: 12 value 2: 23
TypeScript - 類
TypeScript 是面向物件的 JavaScript。TypeScript 支援面向物件程式設計功能,例如類、介面等。就 OOP 而言,類是建立物件的藍圖。類封裝物件的數。Typescript 對此概念提供了內建支援,稱為類。JavaScript ES5 或更早版本不支援類。Typescript 從 ES6 獲取此功能。
建立類
使用 class 關鍵字在 TypeScript 中宣告類。其語法如下:
語法
class class_name { //class scope }
class 關鍵字後跟類名。命名類時必須遵守識別符號規則。
類定義可以包含以下內容:
欄位 - 欄位是在類中宣告的任何變數。欄位表示與物件相關的資料
建構函式 - 負責為類的物件分配記憶體
函式 - 函式表示物件可以執行的操作。它們有時也稱為方法
這些元件組合在一起被稱為類的成員資料。
考慮 typescript 中的 Person 類。
class Person { }
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Person = (function () { function Person() { } return Person; }());
示例:宣告類
class Car { //field engine:string; //constructor constructor(engine:string) { this.engine = engine } //function disp():void { console.log("Engine is : "+this.engine) } }
此示例聲明瞭一個 Car 類。該類有一個名為 engine 的欄位。宣告欄位時不使用 var 關鍵字。上面的示例為該類聲明瞭一個建構函式。
建構函式是類的特殊函式,負責初始化類的變數。TypeScript 使用 constructor 關鍵字定義建構函式。建構函式是一個函式,因此可以引數化。
this 關鍵字指的是類的當前例項。在這裡,引數名稱和類欄位的名稱相同。因此,為了避免歧義,類欄位以 this 關鍵字為字首。
disp() 是一個簡單的函式定義。請注意,這裡沒有使用 function 關鍵字。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Car = (function () { //constructor function Car(engine) { this.engine = engine; } //function Car.prototype.disp = function () { console.log("Engine is : " + this.engine); }; return Car; }());
建立例項物件
要建立類的例項,請使用 new 關鍵字後跟類名。其語法如下:
語法
var object_name = new class_name([ arguments ])
new 關鍵字負責例項化。
表示式的右側呼叫建構函式。如果建構函式已引數化,則應向其傳遞值。
示例:例項化類
var obj = new Car("Engine 1")
訪問屬性和函式
可以透過物件訪問類的屬性和函式。使用“.”點表示法(稱為句點)來訪問類的成員資料。
//accessing an attribute obj.field_name //accessing a function obj.function_name()
示例:將它們放在一起
class Car { //field engine:string; //constructor constructor(engine:string) { this.engine = engine } //function disp():void { console.log("Function displays Engine is : "+this.engine) } } //create an object var obj = new Car("XXSY1") //access the field console.log("Reading attribute value Engine as : "+obj.engine) //access the function obj.disp()
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Car = (function () { //constructor function Car(engine) { this.engine = engine; } //function Car.prototype.disp = function () { console.log("Function displays Engine is : " + this.engine); }; return Car; }()); //create an object var obj = new Car("XXSY1"); //access the field console.log("Reading attribute value Engine as : " + obj.engine); //access the function obj.disp();
上述程式碼的輸出如下:
Reading attribute value Engine as : XXSY1 Function displays Engine is : XXSY1
類繼承
TypeScript 支援繼承的概念。繼承是程式從現有類建立新類的一種能力。擴充套件以建立新類的類稱為父類/超類。新建立的類稱為子類/子類。
類使用“extends”關鍵字從另一個類繼承。子類繼承所有屬性和方法,但私有成員和建構函式除外。
語法
class child_class_name extends parent_class_name
但是,TypeScript 不支援多重繼承。
示例:類繼承
class Shape { Area:number constructor(a:number) { this.Area = a } } class Circle extends Shape { disp():void { console.log("Area of the circle: "+this.Area) } } var obj = new Circle(223); obj.disp()
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Shape = (function () { function Shape(a) { this.Area = a; } return Shape; }()); var Circle = (function (_super) { __extends(Circle, _super); function Circle() { _super.apply(this, arguments); } Circle.prototype.disp = function () { console.log("Area of the circle: " + this.Area); }; return Circle; }(Shape)); var obj = new Circle(223); obj.disp();
上述程式碼的輸出如下:
Area of the Circle: 223
上面的示例聲明瞭一個 Shape 類。Circle 類擴充套件了該類。由於類之間存在繼承關係,子類,即 Car 類,可以隱式訪問其父類的屬性,即 area。
繼承可以分為:
單繼承 - 每個類最多可以從一個父類繼承
多繼承 - 類可以從多個類繼承。TypeScript 不支援多重繼承。
多級繼承 - 下面的示例顯示了多級繼承的工作方式。
示例
class Root { str:string; } class Child extends Root {} class Leaf extends Child {} //indirectly inherits from Root by virtue of inheritance var obj = new Leaf(); obj.str ="hello" console.log(obj.str)
Leaf 類憑藉多級繼承從 Root 類和 Child 類繼承屬性。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Root = (function () { function Root() { } return Root; }()); var Child = (function (_super) { __extends(Child, _super); function Child() { _super.apply(this, arguments); } return Child; }(Root)); var Leaf = (function (_super) { __extends(Leaf, _super); function Leaf() { _super.apply(this, arguments); } return Leaf; }(Child)); var obj = new Leaf(); obj.str = "hello"; console.log(obj.str);
其輸出如下:
輸出
hello
TypeScript ─ 類繼承和方法覆蓋
方法覆蓋是一種機制,子類透過該機制重新定義超類的。下面的示例說明了這一點:
class PrinterClass { doPrint():void { console.log("doPrint() from Parent called…") } } class StringPrinter extends PrinterClass { doPrint():void { super.doPrint() console.log("doPrint() is printing a string…") } } var obj = new StringPrinter() obj.doPrint()
super關鍵字用於引用類的直接父類。此關鍵字可用於引用變數、屬性或方法的超類版本。第13行呼叫doWork()函式的超類版本。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var PrinterClass = (function () { function PrinterClass() { } PrinterClass.prototype.doPrint = function () { console.log("doPrint() from Parent called…"); }; return PrinterClass; }()); var StringPrinter = (function (_super) { __extends(StringPrinter, _super); function StringPrinter() { _super.apply(this, arguments); } StringPrinter.prototype.doPrint = function () { _super.prototype.doPrint.call(this); console.log("doPrint() is printing a string…"); }; return StringPrinter; }(PrinterClass)); var obj = new StringPrinter(); obj.doPrint();
上述程式碼的輸出如下:
doPrint() from Parent called… doPrint() is printing a string…
static關鍵字
static關鍵字可以應用於類的成員資料。靜態變數在其值保留到程式執行結束。靜態成員透過類名來引用。
示例
class StaticMem { static num:number; static disp():void { console.log("The value of num is"+ StaticMem.num) } } StaticMem.num = 12 // initialize the static variable StaticMem.disp() // invoke the static method
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var StaticMem = (function () { function StaticMem() { } StaticMem.disp = function () { console.log("The value of num is" + StaticMem.num); }; return StaticMem; }()); StaticMem.num = 12; // initialize the static variable StaticMem.disp(); // invoke the static method
上述程式碼的輸出如下:
The value of num is 12
instanceof運算子
instanceof運算子如果物件屬於指定的型別,則返回true。
示例
class Person{ } var obj = new Person() var isPerson = obj instanceof Person; console.log(" obj is an instance of Person " + isPerson);
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var Person = (function () { function Person() { } return Person; }()); var obj = new Person(); var isPerson = obj instanceof Person; console.log(" obj is an instance of Person " + isPerson);
上述程式碼的輸出如下:
obj is an instance of Person True
資料隱藏
類可以控制其成員資料對其他類成員的可見性。此功能稱為資料隱藏或封裝。
面向物件使用訪問修飾符或訪問說明符的概念來實現封裝的概念。訪問說明符/修飾符定義類的資料成員在其定義類之外的可見性。
TypeScript支援的訪問修飾符如下:
序號 | 訪問說明符和描述 |
---|---|
1. | public 公共資料成員具有普遍的訪問許可權。類中的資料成員預設是公共的。 |
2. | private 私有資料成員只能在其定義這些成員的類中訪問。如果外部類成員嘗試訪問私有成員,編譯器將丟擲錯誤。 |
3. | protected 受保護的資料成員可被與其相同的類中的成員以及子類成員訪問。 |
示例
現在讓我們來看一個例子,看看資料隱藏是如何工作的:
class Encapsulate { str:string = "hello" private str2:string = "world" } var obj = new Encapsulate() console.log(obj.str) //accessible console.log(obj.str2) //compilation Error as str2 is private
該類具有兩個字串屬性str1和str2,它們分別是公共成員和私有成員。該類已例項化。該示例返回編譯時錯誤,因為私有屬性str2在宣告它的類之外被訪問。
類和介面
類也可以實現介面。
interface ILoan { interest:number } class AgriLoan implements ILoan { interest:number rebate:number constructor(interest:number,rebate:number) { this.interest = interest this.rebate = rebate } } var obj = new AgriLoan(10,1) console.log("Interest is : "+obj.interest+" Rebate is : "+obj.rebate )
AgriLoan類實現了Loan介面。因此,它現在繫結到該類上,將其屬性interest包含為其成員。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var AgriLoan = (function () { function AgriLoan(interest, rebate) { this.interest = interest; this.rebate = rebate; } return AgriLoan; }()); var obj = new AgriLoan(10, 1); console.log("Interest is : " + obj.interest + " Rebate is : " + obj.rebate);
上述程式碼的輸出如下:
Interest is : 10 Rebate is : 1
TypeScript - 物件
一個物件是一個例項,它包含一組鍵值對。值可以是標量值、函式,甚至是其他物件的陣列。語法如下:
語法
var object_name = { key1: “value1”, //scalar value key2: “value”, key3: function() { //functions }, key4:[“content1”, “content2”] //collection };
如上所示,一個物件可以包含標量值、函式和陣列和元組之類的結構。
示例:物件字面量表示法
var person = { firstname:"Tom", lastname:"Hanks" }; //access the object values console.log(person.firstname) console.log(person.lastname)
編譯後,它將在 JavaScript 中生成相同的程式碼。
上述程式碼的輸出如下:
Tom Hanks
TypeScript型別模板
假設你在JavaScript中建立了一個物件字面量,如下所示:
var person = { firstname:"Tom", lastname:"Hanks" };
如果你想向物件新增一些值,JavaScript允許你進行必要的修改。假設我們稍後需要向person物件新增一個函式,這就是你可以這樣做的方式。
person.sayHello = function(){ return "hello";}
如果你在TypeScript中使用相同的程式碼,編譯器會報錯。這是因為在TypeScript中,具體物件應該具有型別模板。TypeScript中的物件必須是特定型別的例項。
你可以使用方法模板在宣告中解決這個問題。
示例:TypeScript型別模板
var person = { firstName:"Tom", lastName:"Hanks", sayHello:function() { } //Type template } person.sayHello = function() { console.log("hello "+person.firstName) } person.sayHello()
編譯後,它將在 JavaScript 中生成相同的程式碼。
上述程式碼的輸出如下:
hello Tom
物件也可以作為引數傳遞給函式。
示例:物件作為函式引數
var person = { firstname:"Tom", lastname:"Hanks" }; var invokeperson = function(obj: { firstname:string, lastname :string }) { console.log("first name :"+obj.firstname) console.log("last name :"+obj.lastname) } invokeperson(person)
該示例聲明瞭一個物件字面量。函式表示式透過傳遞person物件來呼叫。
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var person = { firstname: "Tom", lastname: "Hanks" }; var invokeperson = function (obj) { console.log("first name :" + obj.firstname); console.log("last name :" + obj.lastname); }; invokeperson(person);
其輸出如下:
first name :Tom last name :Hanks
你可以動態建立和傳遞匿名物件。
示例:匿名物件
var invokeperson = function(obj:{ firstname:string, lastname :string}) { console.log("first name :"+obj.firstname) console.log("last name :"+obj.lastname) } invokeperson({firstname:"Sachin",lastname:"Tendulkar"});
編譯後,它將生成以下 JavaScript 程式碼。
//Generated by typescript 1.8.10 var invokeperson = function (obj) { console.log("first name :" + obj.firstname); console.log("last name :" + obj.lastname); }; invokeperson({ firstname: "Sachin", lastname: "Tendulkar" }); invokeperson({ firstname: "Sachin", lastname: "Tendulkar" });
其輸出如下:
first name :Sachin last name :Tendulkar
鴨子型別
在鴨子型別中,如果兩個物件共享相同的屬性集,則認為它們屬於相同的型別。鴨子型別驗證物件中是否存在某些屬性,而不是它們的實際型別,以檢查它們的適用性。這個概念通常用以下短語解釋:
“當我看到一隻鳥像鴨子一樣行走,像鴨子一樣游泳,像鴨子一樣嘎嘎叫,我就稱這隻鳥為鴨子。”
TypeScript編譯器實現了鴨子型別系統,允許動態建立物件,同時保持型別安全。以下示例顯示瞭如何將不顯式實現介面但包含所有必需成員的物件傳遞給函式。
示例
interface IPoint { x:number y:number } function addPoints(p1:IPoint,p2:IPoint):IPoint { var x = p1.x + p2.x var y = p1.y + p2.y return {x:x,y:y} } //Valid var newPoint = addPoints({x:3,y:4},{x:5,y:1}) //Error var newPoint2 = addPoints({x:1},{x:4,y:3})
TypeScript - 名稱空間
名稱空間是一種邏輯分組相關程式碼的方法。這在TypeScript中是內建的,不像JavaScript那樣,變數宣告進入全域性作用域,如果在同一個專案中使用了多個JavaScript檔案,則有可能覆蓋或誤解相同的變數,這將導致JavaScript中的“全域性名稱空間汙染問題”。
定義名稱空間
名稱空間定義以關鍵字namespace開頭,後跟名稱空間名稱,如下所示:
namespace SomeNameSpaceName { export interface ISomeInterfaceName { } export class SomeClassName { } }
應該在名稱空間外部訪問的類或介面應該用關鍵字export標記。
要在另一個名稱空間中訪問類或介面,語法將是namespaceName.className
SomeNameSpaceName.SomeClassName;
如果第一個名稱空間在單獨的TypeScript檔案中,則應使用三斜槓引用語法來引用它。
/// <reference path = "SomeFileName.ts" />
以下程式演示了名稱空間的使用:
FileName :IShape.ts ---------- namespace Drawing { export interface IShape { draw(); } } FileName :Circle.ts ---------- /// <reference path = "IShape.ts" /> namespace Drawing { export class Circle implements IShape { public draw() { console.log("Circle is drawn"); } FileName :Triangle.ts ---------- /// <reference path = "IShape.ts" /> namespace Drawing { export class Triangle implements IShape { public draw() { console.log("Triangle is drawn"); } } FileName : TestShape.ts /// <reference path = "IShape.ts" /> /// <reference path = "Circle.ts" /> /// <reference path = "Triangle.ts" /> function drawAllShapes(shape:Drawing.IShape) { shape.draw(); } drawAllShapes(new Drawing.Circle()); drawAllShapes(new Drawing.Triangle()); } } }
可以使用以下命令編譯和執行上述程式碼:
tsc --out app.js TestShape.ts node app.js
編譯後,它將生成以下JavaScript程式碼(app.js)。
//Generated by typescript 1.8.10 /// <reference path = "IShape.ts" /> var Drawing; (function (Drawing) { var Circle = (function () { function Circle() { } Circle.prototype.draw = function () { console.log("Cirlce is drawn"); }; return Circle; }()); Drawing.Circle = Circle; })(Drawing || (Drawing = {})); /// <reference path = "IShape.ts" /> var Drawing; (function (Drawing) { var Triangle = (function () { function Triangle() { } Triangle.prototype.draw = function () { console.log("Triangle is drawn"); }; return Triangle; }()); Drawing.Triangle = Triangle; })(Drawing || (Drawing = {})); /// <reference path = "IShape.ts" /> /// <reference path = "Circle.ts" /> /// <reference path = "Triangle.ts" /> function drawAllShapes(shape) { shape.draw(); } drawAllShapes(new Drawing.Circle()); drawAllShapes(new Drawing.Triangle());
編譯並執行上述程式碼後,將產生以下結果:
Circle is drawn Triangle is drawn
巢狀名稱空間
你可以像這樣在一個名稱空間內定義另一個名稱空間:
namespace namespace_name1 { export namespace namespace_name2 { export class class_name { } } }
你可以使用點(.)運算子訪問巢狀名稱空間的成員,如下所示:
FileName : Invoice.ts namespace tutorialPoint { export namespace invoiceApp { export class Invoice { public calculateDiscount(price: number) { return price * .40; } } } } FileName: InvoiceTest.ts /// <reference path = "Invoice.ts" /> var invoice = new tutorialPoint.invoiceApp.Invoice(); console.log(invoice.calculateDiscount(500));
可以使用以下命令編譯和執行上述程式碼:
tsc --out app.js InvoiceTest.ts node app.js
編譯後,它將生成以下JavaScript程式碼(app.js)。
//Generated by typescript 1.8.10 var tutorialPoint; (function (tutorialPoint) { var invoiceApp; (function (invoiceApp) { var Invoice = (function () { function Invoice() { } Invoice.prototype.calculateDiscount = function (price) { return price * .40; }; return Invoice; }()); invoiceApp.Invoice = Invoice; })(invoiceApp = tutorialPoint.invoiceApp || (tutorialPoint.invoiceApp = {})); })(tutorialPoint || (tutorialPoint = {})); /// <reference path = "Invoice.ts" /> var invoice = new tutorialPoint.invoiceApp.Invoice(); console.log(invoice.calculateDiscount(500));
編譯並執行上述程式碼後,將產生以下結果:
200
TypeScript - 模組
模組的設計理念是組織用TypeScript編寫的程式碼。模組大致分為:
- 內部模組
- 外部模組
內部模組
內部模組出現在早期版本的TypeScript中。它用於將類、介面、函式邏輯地分組到一個單元中,並可以在另一個模組中匯出。這種邏輯分組在最新版本的TypeScript中被稱為名稱空間。因此,內部模組已過時,我們可以使用名稱空間代替。內部模組仍然受支援,但建議使用名稱空間而不是內部模組。
內部模組語法(舊)
module TutorialPoint { export function add(x, y) { console.log(x+y); } }
名稱空間語法(新)
namespace TutorialPoint { export function add(x, y) { console.log(x + y);} }
兩種情況下生成的JavaScript相同
var TutorialPoint; (function (TutorialPoint) { function add(x, y) { console.log(x + y); } TutorialPoint.add = add; })(TutorialPoint || (TutorialPoint = {}));
外部模組
TypeScript中的外部模組用於指定和載入多個外部js檔案之間的依賴關係。如果只使用一個js檔案,則外部模組不相關。傳統上,JavaScript檔案之間的依賴關係管理是使用瀏覽器指令碼標籤(<script></script>)完成的。但這不可擴充套件,因為它在載入模組時非常線性。這意味著沒有非同步選項來載入模組,而不是一個接一個地載入檔案。例如,當你為伺服器(例如NodeJs)編寫js程式時,你甚至沒有指令碼標籤。
從單個主JavaScript檔案載入依賴js檔案有兩種場景。
- 客戶端 - RequireJs
- 伺服器端 - NodeJs
選擇模組載入器
為了支援載入外部JavaScript檔案,我們需要一個模組載入器。這將是另一個js庫。對於瀏覽器,最常用的庫是RequieJS。這是AMD(非同步模組定義)規範的實現。AMD可以分別載入所有檔案,即使它們相互依賴,而不是一個接一個地載入檔案。
定義外部模組
在針對CommonJS或AMD的TypeScript中定義外部模組時,每個檔案都被視為一個模組。因此,在外部模組中使用內部模組是可選的。
如果你正在將TypeScript從AMD遷移到CommonJs模組系統,則不需要額外的工作。唯一需要更改的是編譯器標誌。與JavaScript不同,從CommonJs遷移到AMD或反之亦然存在開銷。
宣告外部模組的語法是使用關鍵字“export”和“import”。
語法
//FileName : SomeInterface.ts export interface SomeInterface { //code declarations }
要在另一個檔案中使用已宣告的模組,請使用如下所示的import關鍵字。僅指定檔名,不使用副檔名。
import someInterfaceRef = require(“./SomeInterface”);
示例
讓我們用一個例子來理解這一點。
// IShape.ts export interface IShape { draw(); } // Circle.ts import shape = require("./IShape"); export class Circle implements shape.IShape { public draw() { console.log("Cirlce is drawn (external module)"); } } // Triangle.ts import shape = require("./IShape"); export class Triangle implements shape.IShape { public draw() { console.log("Triangle is drawn (external module)"); } } // TestShape.ts import shape = require("./IShape"); import circle = require("./Circle"); import triangle = require("./Triangle"); function drawAllShapes(shapeToDraw: shape.IShape) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle());
為AMD系統編譯主TypeScript檔案的命令是:
tsc --module amd TestShape.ts
編譯後,它將為AMD生成以下JavaScript程式碼。
檔案:IShape.js
//Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { });
檔案:Circle.js
//Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { var Circle = (function () { function Circle() { } Circle.prototype.draw = function () { console.log("Cirlce is drawn (external module)"); }; return Circle; })(); exports.Circle = Circle; });
檔案:Triangle.js
//Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { var Triangle = (function () { function Triangle() { } Triangle.prototype.draw = function () { console.log("Triangle is drawn (external module)"); }; return Triangle; })(); exports.Triangle = Triangle; });
檔案:TestShape.js
//Generated by typescript 1.8.10 define(["require", "exports", "./Circle", "./Triangle"], function (require, exports, circle, triangle) { function drawAllShapes(shapeToDraw) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle()); });
為Commonjs系統編譯主TypeScript檔案的命令是
tsc --module commonjs TestShape.ts
編譯後,它將為Commonjs生成以下JavaScript程式碼。
檔案:Circle.js
//Generated by typescript 1.8.10 var Circle = (function () { function Circle() { } Circle.prototype.draw = function () { console.log("Cirlce is drawn"); }; return Circle; })(); exports.Circle = Circle;
檔案:Triangle.js
//Generated by typescript 1.8.10 var Triangle = (function () { function Triangle() { } Triangle.prototype.draw = function () { console.log("Triangle is drawn (external module)"); }; return Triangle; })(); exports.Triangle = Triangle;
檔案:TestShape.js
//Generated by typescript 1.8.10 var circle = require("./Circle"); var triangle = require("./Triangle"); function drawAllShapes(shapeToDraw) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle());
輸出
Cirlce is drawn (external module) Triangle is drawn (external module)
TypeScript - 環境宣告
環境宣告是一種告訴TypeScript編譯器實際原始碼存在於其他位置的方法。當你使用一堆第三方js庫(如jquery/angularjs/nodejs)時,你無法用TypeScript重寫它。在使用這些庫時確保型別安全和智慧感知對於TypeScript程式設計師來說將是一個挑戰。環境宣告有助於將其他js庫無縫整合到TypeScript中。
定義環境
按照約定,環境宣告儲存在副檔名為(d.ts)的型別宣告檔案中。
Sample.d.ts
上述檔案不會被編譯成JavaScript。它將用於型別安全和智慧感知。
宣告環境變數或模組的語法如下:
語法
declare module Module_Name { }
環境檔案應在客戶端TypeScript檔案中引用,如下所示:
/// <reference path = " Sample.d.ts" />
示例
讓我們透過一個例子來理解這一點。假設你得到一個類似於此程式碼的第三方JavaScript庫。
FileName: CalcThirdPartyJsLib.js var TutorialPoint; (function (TutorialPoint) { var Calc = (function () { function Calc() { } Calc.prototype.doSum = function (limit) { var sum = 0; for (var i = 0; i <= limit; i++) { Calc.prototype.doSum = function (limit) { var sum = 0; for (var i = 0; i <= limit; i++) { sum = sum + i; return sum; return Calc; TutorialPoint.Calc = Calc; })(TutorialPoint || (TutorialPoint = {})); var test = new TutorialPoint.Calc(); } } } } }
作為TypeScript程式設計師,你將沒有時間將此庫重寫為TypeScript。但你仍然需要使用doSum()方法並保證型別安全。你可以做的是環境宣告檔案。讓我們建立一個環境宣告檔案Calc.d.ts
FileName: Calc.d.ts declare module TutorialPoint { export class Calc { doSum(limit:number) : number; } }
環境檔案不包含實現,它只是型別宣告。現在需要在TypeScript檔案中包含宣告,如下所示。
FileName : CalcTest.ts /// <reference path = "Calc.d.ts" /> var obj = new TutorialPoint.Calc(); obj.doSum("Hello"); // compiler error console.log(obj.doSum(10));
以下程式碼行將顯示編譯器錯誤。這是因為在宣告檔案中,我們指定了輸入引數將是數字。
obj.doSum("Hello");
註釋掉上面的行並使用以下語法編譯程式:
tsc CalcTest.ts
編譯後,它將生成以下JavaScript程式碼(CalcTest.js)。
//Generated by typescript 1.8.10 /// <reference path = "Calc.d.ts" /> var obj = new TutorialPoint.Calc(); // obj.doSum("Hello"); console.log(obj.doSum(10));
為了執行程式碼,讓我們新增一個帶有指令碼標籤的html頁面,如下所示。新增編譯後的CalcTest.js檔案和第三方庫檔案CalcThirdPartyJsLib.js。
<html> <body style = "font-size:30px;"> <h1>Ambient Test</h1> <h2>Calc Test</h2> </body> <script src = "CalcThirdPartyJsLib.js"></script> <script src = "CalcTest.js"></script> </html>
它將顯示以下頁面:

在控制檯中,你可以看到以下輸出:
55
同樣,您可以根據需要將 jquery.d.ts 或 angular.d.ts 整合到專案中。