TypeScript學習

chenjk4發表於2020-11-19

TS知識

TS基礎

一、基礎型別

資料型別關鍵字描述
任意型別any宣告為any的變數可以賦予任意型別的值
數字型別number雙精度64位浮點值。它可以用來表示整數和分數
字串型別string一個字元系列,使用單引號(‘)或雙引號("")來表示字串型別,反引號(`)來定義多行文字和內嵌表示式
布林型別boolean表示邏輯值:true和false let flag : boolean = true
陣列型別宣告變數為陣列 // 在元素型別後面加上[] let arr : number[] = [1,2];
元組元組型別用來表示已知元素數量和型別的陣列,各元素的型別不必相同 let x :[string, number]; x= ['cjk' ,1]
列舉enum列舉型別用於定義數值集合 enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 輸出 2
voidvoid用於表示方法返回的型別,表示該方法沒有返回值
nullnull表示物件值缺失
undefinedundefined用於初始化變數為一個未定義的值
nevernevernever是其它型別(包括null和undefined)的子型別,代表從不會出現的 值。

注意:TypeScript和JavaScript 沒有整數型別

二、變數宣告

1、型別斷言(Type Assertion)

型別斷言可以用來手動指定一個值的型別,即允許變數從一種型別更改為另一種型別。
語法格式:
<型別> 值

值 as 型別
例項

var str = '1';
var str2:number = <number><any> str //str、str2是string型別
console.log(str2)

2、型別推斷

當型別沒有給出時,TypeScript 編譯器利用型別推斷來推斷型別
如果由於缺乏宣告而不能推斷出型別,那麼它的型別被視為預設的動態any型別。

var num = 2;
console.log("num 變數的值為"+num);
num = "12";
console.log(num);
  • 第一行程式碼宣告瞭變數num 並設定初始值為2,注意變數宣告沒有指定型別。因此,程式使用型別推斷來確定變數的資料型別,第一次賦值為2,num設定為number型別。
  • 第三行程式碼,當我們再次為變數設定字串型別的值時,這時編譯會錯誤,因為變數已經設定為number型別
    error TS2332 : Type '"12"' is not assignable to type ''number

三、運算子

1、算術運算子

同java、js

2、關係運算子

== 、 > 、< 、等
同java、js

3、邏輯運算子

&& 、|| 、!
同java、js

4、短路運算子

&& 、||
如果前面為false,&&後者不執行

5、位運算子

運算子描述例子類似於結果
~取反,取反是一元運算子,對一個二進位制的每一位執行邏輯反操作。使數字1成為0,0成為1x=~5~01011010,即 -6(補碼 = 原碼取反 + 1)

位運算子同java

6、賦值運算子

同java

7、三元運算子

同Java

8、型別運算子

8.1、typeof運算子

typeof是一元運算子,返回運算元的資料型別。

var num = 12;
console.log(typeof num); // 輸出結果:number
8.2、instanceof

instanceof 運算子用於判斷物件是否為指定的型別。

9、其他運算子

9.1負號運算子(-)

更改運算元的符號

var x:number = 4;
var y = -x;
console.log("x 值為:",x); // 輸出結果為4
console.log("y 值為:",y); //輸出結果為-4
10、字串運算子:連線運算子(+)

+運算子可以拼接兩個字串

var msg:string = "chenjk4"+".com";
console.log(msg);

四、條件語句

1、switch…case 語句

switch語句必須遵循下面的規則:

  • switch 語句中的expression是一個常量表示式,必須是一個整型或列舉型別
  • 不是每一個case都需要包含break。如果case語句不包含break,控制流將會繼續後續的case,直到遇到break

– ts迴圈

1、for…in迴圈

for…in 語句用於一組值的集合或列表進行迭代輸出
語法

 for(var val in list){
 }
 var j:any;
 var n:any = "a b c";
 for(j in n){
	console.log(n[j])
}

2、for…of迴圈

let someArray = [1,"string",false];
for(let entry of someArray){
	console.log(entry);
}

3、forEach、every、while

3.1forEach
let list = [4,5,6];
list.forEach((val, idx, array)=>){
	//val :當前值
	//idx:當前index
	//array : Array
})

因為forEach 在iteration中無法返回,所以可以使用every和some來取代forEach。

3.2every
let list = [4,5,6];
list.every((val, idx, array) =>{
	//val :當前值
	//idx:當前index
	//array:Array
	return true;
})

五、函式

基本同java函式

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}
let result1 = buildName("Bob");                  // 錯誤,缺少引數
let result2 = buildName("Bob", "Adams", "Sr.");  // 錯誤,引數太多了
let result3 = buildName("Bob", "Adams");         // 正確

1、可選引數和預設引數

可選引數
在TypeScript函式裡,如果我們定義了引數,則我們必須傳入這些引數,除非將這些引數設定為可選,可選引數使用問號?。

function buildName(firstName :string, lastName?:string){
		if(lastName){
			return firstName + "" + lastName;
		}else{
			return firstName;
		}
}
let result1 = buildName("Bob"); // 正確
let result2 = buildName("Bob“,"Adams","cjk"); //錯誤,引數太多了
let result3 = buldName("Bob","Adams"); //正確

可選引數必須跟在必需引數後面。 如果上例我們想讓 firstName 是可選的,lastName 必選,那麼就要調整它們的位置,把 firstName 放在後面。

2、預設引數

我們也可以設定引數的預設值,這樣在呼叫函式的時候,如果不傳入該引數的值,則使用預設引數。

function calculate_discount(price :number , rate:number = 0.50){
	var discount = price * rate;
	console.log("計算結果:",discount);
}
calculate_discount(1000);
calculate_discount(1000,0.30);

3、剩餘引數

有一種情況,我們不知道向函式傳入多少個引數,這時候我們就可以使用剩餘引數來定義。
剩餘引數語法允許我們將一個不確定數量的引數作為一個陣列傳入。

function buildName(firstName:string, ...restOfName : string[]){
	return firstName + "" + restOfName.join(" ");
}
let employeeName

4、匿名函式

匿名函式是一個沒有函式名的函式
匿名函式在程式執行時動態宣告,除了沒有函式名外,其他的與標準函式一樣。
我們可以將匿名函式賦值一個變數,這種表示式就成為函式表示式。

var res = function([arguments]){...}

var msg = function(){
	return "helli world";
}
console.log(msg()); // 輸出hello world

var res = function(a:number,b:number){
return a*b;
}
console.log(res(12,2)); //輸出24

5、匿名函式自呼叫

匿名函式自呼叫在函式後使用()即可

(function(){
	  var x = "hello!";
	  console.log(x);
})();

6、建構函式

TypeScript 也支援使用JavaScript 內建的建構函式Function()來定義函式

var res = new Function([arg1[,arg2[,...argN]],] functionBody)
- arg1,arg2...argN:引數列表
- functionBody: 一個含有包括函式定義的JavaScript語句的字串
var myFunction = new Function("a","b","return a*b");
var x = myFunction(4,3);
console.log(x); //輸出12

7、Lambda 函式

Lambda 函式也稱之為箭頭函式
箭頭函式表示式的語法比函式表示式更短
函式只有一行語句
([param1,param2,…paramN]) => statement;

var foo = (x:number) => {
     x = 10+x;
     console.log(foo(100));
     }
     foo(100) ; // //輸出110

六、Number物件

1、物件屬性

序號屬性&描述
1prototype Number物件的靜態屬性。使您有能力向物件新增屬性和方法。
2constructor 返回對建立此物件的Number函式的引用
3NaN 非數字值(Not-A-Number)
1.1、NaN例項
var month = 0;
if(month<=0 || month>12){
	month = Number.NaN;
	console.log("月份是:”+ month);
}else{
	console.log("正確");
}
1.2、prototype 例項
function employee(id:number,name:string){
	this.id = id ;
	this.name = name;
}
var emp = new emplpyee(123,"cjk“);
employee.prototype.email = "chenjk4@gamil.com";

console.log("員工號:"+emp.id);
console.log("員工姓名:"+emp.name);
console.log("員工郵箱:"+emp.email)

2、Number物件方法

Number物件,支援以下方法

序號方法&描述例項
1toExponential 把物件的值轉換為指數計數法//toExponential()
var num1 = 1225.30
var val = num1.toExponential();·
console.log(val) // 輸出: 1.2253e+3
2.1、toFixed()

把數字轉換成為字串,並對小數點指定位數

var num3 = 177.234;
console.log("num3.toFixed()為" + num3.toFixed()) ; //輸出:177
console.log("num3.toFixed(2)為"+ num3.toFixed(2)); // 輸出:177.23
console.log("num3.toFixed(6)為"+ num3.toFixed(6)); 
//輸出:177.234000
2.2、toPrecision()

把數字格式化為指定的長度

var num = new Number(7.123456);
console.log(num.toPrecision()); // 輸出:7.123456
console.log(num.toPrecision(1)); //輸出:7
console.log(num.toPrecision(2)); //輸出:7.1
2.3、toString()

把數字轉換為字串,使用指定的基數。數字的基數是2~36之間的整數。若省略該引數,則使用基數10.

var num = new Number(10);
console.log(num.toString()); //輸出10進位制:10
console.log(num.toString(2)); //輸出2進位制:1010
console.log(num.toString(8)) ;// 輸出8進位制:12
2.3、valueOf()

返回一個Number物件的原始數字值

var num = new Number(10);
console.log(num.valueOf()); //輸出:10

七、String (字串)

1、String物件屬性

1.1、constructor

對建立該物件的函式引用

var str = new String("This is string");
console.log("str.constructor is:"+str.constructor);
//輸出結果
str.constructor is : function String(){ [native code] }
1.2、prototype

允許您向物件新增屬性和方法

function employee(id:number,name:string){
	this.id = id ;
	this.name = name;
}
var emp  = new employee(123,"cjk");
employee.prototype.email="chenjk4@gamil.com" // 新增屬性 email
console.log("員工號: "+emp.id) 
console.log("員工姓名: "+emp.name) 
console.log("員工郵箱: "+emp.email)

八、Array(陣列)

陣列物件是使用單獨的變數名來儲存一系列的值

var sites : string[];
sites = ["Google","Runoob","Taobao"];

//或者
var numlist : number[] = [2,4,6,8];

1、資料解構

我們也可以把陣列元素賦值給變數,如下所示

var arr:number[] = [12,13];
var[x,y] = arr; //將陣列的兩個元素賦值給變數x和y
console.log(x);
console.log(y);

2、陣列迭代

我們可以使用for語句來迴圈輸出陣列各個元素

var j:any;
var nums: number[] = [1001,1002,1003,1004];

for(j in nums){
	 console.log(nums);
}

3、陣列方法

3.1、concat()

連線兩個或更多陣列,並返回結果

var alpha = ["a","b","c"];
var number = [1,2,3];

var alphaNum = alpha.concat(number);
console.log("alphaNum : " + alphaNum ); // a,b,c,1,2,3
3.2、every()

檢測數值元素的每個元素是否都符合條件

function isBigEnough(elemet , index, array){
	return (element >= 10);
}

var passed = [12,5,8,130,44].every(isBigEnough);
console.log("Test value:" + passed); //false
3.3、filter()

檢測數值元素,並返回符合條件所有元素的陣列

function isBigEnough(element, index, array){
	return (element >= 10);
}
var passed = [21,5,6,130,44].filter(isBigEnough);
console.log("Test Value:"+ passed); //21,130,44
3.4、forEach()

陣列每個元素都執行一次回撥函式

let num = [7,8,9];
num.forEach(function(value){
	console.log(value);
});
3.5、indexOf()

搜尋陣列中的元素,並返回它所在的位置。如果搜尋不到,返回值-1,代表沒有此項

var inde = [12,5,8,130,44].indexOf(8);
console.log("index is: " + index); //2
3.6、join()

把陣列的所有元素放入一個字串

var arr = new Array("First","Second","Third");
var str = arr.join();
console.log("str:"+ str); //First,Second,Third

var  str = arr.join(" + ");
console.log("str:"+ str); //First + Second + Third
3.7、lastIndexOf()

返回一個指定的字串值最後出現的位置,在一個字串中的指定位置從後向前搜尋

var index = [12,5,8,130,44].lastIndexOf(8);
coosole.log("index is : "+index); // 2
3.8、map()

通過指定函式處理陣列的每個元素,並返回處理後的陣列

var numbers = [1,4,9];
var roots = numbers.map(Math.sqrt); //開根號
console.log("roots is : "+ roots); //1,2,3
3.9、pop()

刪除陣列的最後一個元素並返回刪除的元素

var numbers = [1,4,9];
var element = numbers.pop();
console.log("element is :" + element); //9
var element = numbers.pop();
console.log("element is : " + element); //4  
3.10、push()

向陣列的末尾新增一個或更多元素,並返回新的長度

var numbers = new Array(1,4,9);
var length = numbers.push(10);
console.log("new numbrees is : " + numbers); //1,4,9,10
length = numbers.push(20);
console.log("new numbers is :"+ numbers); //1,4,9,10,20
3.11、reduce()/reduceRight()

將陣列元素計算為一個值(從左到右) (reduceRight()從右到左)

var total = [0,1,2,3].reduce(function(a,b){
	return a +b;
});
console.log("total is :" + total); //6
3.12、reverse()

反轉陣列的元素資料

var arr = [0,1,2,3].reverse();
console.log("Reversed array is : " + arr); //3,2,1,0
3.13、shift()

刪除並返回陣列的第一個元素

var arr = [10,1,2,3].shift();
console.log("Shifted value is :" + arr); //10
3.14、slice()

選取陣列的一部分,並返回一個新的陣列

var arr = ["orange", "mango","banana","sugar","tea"];
console.log("arr.slice(1,2) :" + arr.slice(1,2)); // mango
console.log("arr.slice(1,3) :" + arr.slice(1,2)); // mango,banana
3.15、some()

檢測陣列元素中是否有元素符合指定條件

function isBigEnough(element, index, array){
	return (element >= 10);
}
var retval = [2,,5,8,1,4].some(isBigEnough);
console.log("value:" + retval ) ; // false

var retval = [12,5,8,1,4].some(isBigEnough);
console.log("value:"+ retval); // true
3.16、sort()

對陣列的元素進行排序

var arr = new Array("orange","mango","banana","sugar");
var sorted = arr.sort();
console.log("return string is :"+ sorted); // banana,mango,orange,sugar
3.17、splice()

從陣列中新增或刪除元素 (0:新增,1:刪除)

var arr = ["orange", "mango", "banana", "sugar","tea"];
var removed = arr.splice(2,0,"water");
console.log("After adding 1:" + arr); //orange,mango,water,banana
removed = arr.splice(3,1);
console.log("After removing 1:" + arr); //orange,mango,water,sugar,tea
console.log(”remmoved is :“ + removed); //banana
3.18、toString()

把陣列轉換為字串,並返回結果

var arr = new Array("orange","mango","banana","sugar");
var str = arr.toString();
console.log(""+ str) ; // orange,mango,banana,sugar
3.19、unshift()

向陣列的開頭新增一個或更多元素,並返回新的長度

var arr = new Array("orange","mango","banana","sugar");
var length = arr;unshift("water");
console.log("Returned array is : " + arr); //water, orange,mango,banana,sugar
console.log(""+ length); //5

九、Map物件

Map物件儲存鍵值對,並且能夠記住鍵的原始插入順序。
任何值(物件或原始值)都可以作為一個鍵或一個值。

1、建立Map

TypeScript 使用Map型別和new關鍵字來建立Map:
Map 相關的函式與屬性:

  • map.clear() – 移除 Map 物件的所有鍵/值對 。
  • map.set() – 設定鍵值對,返回該 Map 物件。
  • map.get() – 返回鍵對應的值,如果不存在,則返回 undefined。
  • map.has() – 返回一個布林值,用於判斷 Map 中是否包含鍵對應的值。
  • map.delete() – 刪除 Map 中的元素,刪除成功返回 true,失敗返回 false。
  • map.size – 返回 Map 物件鍵/值對的數量。
  • map.keys() - 返回一個 Iterator 物件, 包含了 Map 物件中每個元素的鍵 。
  • map.values() – 返回一個新的Iterator物件,包含了Map物件中每個元素的值 。

2、迭代Map

Map物件中的元素是按順序插入的,我們可以迭代Map物件,每一次迭代返回[key,value]。

let nameSiteMapping = new Map();
nameSiteMapping.set("Google",1);
nameSiteMapping.set("sf",2);
nameSiteMapping.set("tx",3);

//迭代Map中的key
for( let key of nameSiteMapping.keys()){
	console.log(key);
}
//迭代Map中的value
for(let value of nameSiteMapping.values()){
	console.log(value);
}
//迭代Map中的key=>value
for(let entry of nameSiteMapping.entries()){
	console.log(entry[0],entry[1]);
}
//使用物件解析
for(let [key,value] of nameSiteMapping){
	console.log(key,value);
}

//輸出結果為:
Google
Runoob
Taobao
1
2
3
Google 1
Runoob 2
Taobao 3
Google 1
Runoob 2

十、元組

1、解構元組

我們可以把元組元素賦值給變數

var  a = [10,"Runnoob"];
var [b,c] = a;
console.log(b);
console.log(c);
//輸出結果
10
Runoob

十一、聯合型別

聯合型別(Union Types)可以通過管道(|)將變數設定多種型別,賦值時可以根據設定的型別來賦值。
注意:只能賦值指定的型別,如果賦值其它型別就會報錯。

Type|Type1|Type2

//例項
var val:string|number
val = 12;
console.log("數字為 "+val);
val = "Runoob";
console.log("字串為"+ val);

將聯合型別作為函式引數使用

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("Runoob");
disp(["Runoob","Google","Taobao"]);

1、聯合型別陣列

var arr:number[] | string[];
var i:number;
arr = [1,2,4];
console.log("");

for(i = 0;i<arr.length;i++){
	console.log(arr[i]);
}
arr = ["Runoob","Google","Taobao"]
console.log("")
for(i = 0;i<arr.length;i++){
	console.log(arr[i]);
}

十二、TypeScript介面

介面時一系列抽象方法的宣告,是一些方法特徵的集合,這些方法都應該是抽象的,需要由具體的類去實現,抽象方法呼叫,讓具體的類執行具體的方法

interface interface_name{
}

例項

//介面IPerson
interface IPerson{
	firstName : string,
	lastName : string,
	sayHi:()=> string
}
//實現介面
var customer:IPerson = {
		firstName : "Tom",
		lastName : "Hanks",
		sayHi:():string =>{return "Hi there"}
}
//呼叫具體物件的方法
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  物件 ") 
console.log(employee.firstName) 
console.log(employee.lastName)

介面不能轉成JavaScript,它只是TypeScript的一部分

1、聯合型別和介面

interface RunOptions{
	program: string;
	commandline : string[] | string | (()=>string);
}

//commandline 是字串
var options : RunOptions = {program:"test1", commandline : "Hello"};
console.log(options.commandline)

//commandline 是字串陣列
options = {program:"test1", commandline:["Hello","World"]};
console.log(options.commandline[0]);
console.log(options.commandline[1]);

//commandline 是一個函式表示式
options = {program : "test1",commandline: ()=> {return "Hello World"}};

var fn:any = options.commandline;
console.log(fn());

2、介面和陣列

介面中我們可以將陣列的索引值和元素設定為不同型別,索引值可以是數字或字串

interface namelist{
	[index:number] : string
}
var list2:namelist = ["John", 1 , "Bran"] //錯誤元素1 不是string型別
interface ages{
	[index : string] : number
}
var agelist : ages;
agelist["John"] = 15 // 正確
agelist[2] = "nine" //錯誤, index為string型別

3、介面繼承

介面繼承就是說介面可以通過其他介面來擴充套件自己
TypeScript 允許介面繼承多個介面
繼承使用關鍵字extends
單介面繼承語法格式:

Child_interface_name extends super_interface_name

多介面繼承語法格式:

Child_interface_name extends super_interface1_name,super_interface2_name,...

4、多繼承

interface IParent1{
	v1: number
}
interface IParent2{
	v2:number
}
interface Child extends IParent1, IParent2{}
var Iobj : Child = { v1:12, v2:23}
console.log("value 1:"+ Iobj.v1 + "value 2:"+ Iobj.v2);

十三、TypeScript類

TypeScript是物件導向的JavaScript.
類描述了所建立的物件共同的屬性和方法
TypeScript 支援物件導向的所有特性,比如類、介面等
定義類的關鍵字為class,後面緊跟類名,類可以包含以下幾個模組(類的資料成員):

  • ** 欄位** -欄位是類裡面宣告的變數。欄位表示物件的有關資料
  • ** 建構函式** -類例項化時呼叫,可以為類的物件分配記憶體
  • 方法 -方法為物件要執行的操作

例項

class Person{}

1、建立類的資料成員

this關鍵字表示當前類例項化的物件。注意建構函式的引數名與欄位名相同,this.engine表示類的欄位

class Car{
	//欄位
	engine : string;
	//建構函式
	constructor(engine:string){
		   this.engine = engine;
	}
	//方法
	disp():void{
			console.log("發動機為:"+this.engine)
	}
}

2、例項化物件

class Car{
	//欄位
	engine : string;
	costructor(engine : string){
			this.engine = engine;
	}
	disp():void{
		 	console.log(""+this.engine);
	}
}
//建立一個物件
var obj = new Car("XXSY1");
//訪問欄位
console.log(obj.engine+"");
obj.disp();

3、類的繼承

同java

4、繼承類的方法重寫

同java

5、static關鍵字

同java

6、instanceof 運算子

同java
var isPersion = obj instanceof Persion

7、訪問控制修飾符

  • public (預設):公有,可以在任何地方被訪問
  • protected : 受保護,可以被其自身以及其子類和父類訪問
  • privater :私有,只能被其定義所在的類訪問

8、類和介面

類可以實現介面,使用關鍵字implements,並將interest欄位作為類的屬性使用。

interface ILoan{
	interest : number
}
class AgriLoan implements ILoan{
	interest : number
	rebate : number
	constructor(interest:number,rebate:number){
		   this.interest = interset;
		   this.rebate = rebate;
	}
}

var obj = new AgriLoan(10,1);
console.log("利潤為:" + obj.interest + ",抽成:"+ obj.rebate);

9、TypeScript物件

物件是包含一組鍵值對的例項。值可以是標量、函式、陣列、物件等

var object_name = {
		key1: "value1",
		key2: "value2",
		key3: function(){
			//函式
		},
		key4:["content1","content2"] //集合
}

以上物件包含了標量,函式,集合(陣列或元組)

10、物件例項

var sites = {
	 site1 : "Runoob",
	 site2 : "Google"
};
//訪問物件的值
console.log(sites.site1);
console.log(sites.site2);

11、TypeScript型別模板

Typescript中的物件必須是特定型別的例項

var sites = {
		site1: "Runoob",
		site2: "Google",
		sayHello : function(){} //型別模板
};
sites.sayHello = function(){
	    console.log("hello" + sites.site1);
};
sites.sayHello();

此外物件也可以作為一個引數傳遞給函式

var sites = {
		site1 : "Runoob",
		site2:  "Google"
};
var invokesites = function(obj : {site1:string, site2: string}){
	  console.log("site1:"+ obj.site1);
	  console.log("site2:"+ obj.site2);
}
invokesites(sites);

12、Duck Typing

動態型別的一種風格,是多型的一種形式
在這種風格中,一個物件有效的語義,不是由繼承自特定的類或實現特定的介面,而是由"當前方法和屬性的集合"決定。
在鴨子型別中,關注點在於物件的行為,能作什麼;而不是關注物件所屬的型別。例如,在不使用鴨子型別的語言中,我們可以編寫一個函式,它接受一個型別為"鴨子"的物件,並呼叫它的"走"和"叫"方法。在使用鴨子型別的語言中,這樣的一個函式可以接受一個任意型別的物件,並呼叫它的"走"和"叫"方法。如果這些需要被呼叫的方法不存在,那麼將引發一個執行時錯誤。任何擁有這樣的正確的"走"和"叫"方法的物件都可被函式接受的這種行為引出了以上表述,這種決定型別的方式因此得名。

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} 
} 
 
// 正確
var newPoint = addPoints({x:3,y:4},{x:5,y:1})  
 
// 錯誤 
var newPoint2 = addPoints({x:1},{x:4,y:3})

十四、TypeScript名稱空間

區分範圍
TypeScript中名稱空間使用namespace來定義,語法格式如下:

namespace SomeNameSpaceName{
	export interface ISomeInterfaceName{}
	export class SomeClassName{}
}

以上定義了一個名稱空間 SomeNameSpaceName,如果我們需要在外部可以呼叫 SomeNameSpaceName 中的類和介面,則需要在類和介面新增 export 關鍵字。

要在另外一個名稱空間呼叫語法格式為:

SomeNameSpaceName.SomeClassName;
如果一個名稱空間在一個單獨的 TypeScript 檔案中,則應使用三斜槓 /// 引用它,語法格式如下:

/// <reference path = "SomeFileName.ts" />

IShape.ts 檔案程式碼:

namespace Drawing { 
    export interface IShape { 
        draw(); 
    }
}

Circle.ts 檔案程式碼:

/// <reference path = "IShape.ts" /> 
namespace Drawing { 
    export class Circle implements IShape { 
        public draw() { 
            console.log("Circle is drawn"); 
        }  
    }
}

Triangle.ts 檔案程式碼:

/// <reference path = "IShape.ts" /> 
namespace Drawing { 
    export class Triangle implements IShape { 
        public draw() { 
            console.log("Triangle is drawn"); 
        } 
    } 
}

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());

輸出

$ node app.js
Circle is drawn
Triangle is drawn

1、巢狀名稱空間

名稱空間支援巢狀,即你可以將名稱空間定義在另外一個名稱空間裡頭。

namespace namespace_name1 { 
    export namespace namespace_name2 {
        export class class_name {    } 
    } 
}

成員的訪問使用點號 . 來實現,如下例項:
Invoice.ts 檔案程式碼:

namespace Runoob { 
   export namespace invoiceApp { 
      export class Invoice { 
         public calculateDiscount(price: number) { 
            return price * .40; 
         } 
      } 
   } 
}

InvoiceTest.ts 檔案程式碼:

/// <reference path = "Invoice.ts" />
var invoice = new Runoob.invoiceApp.Invoice(); 
console.log(invoice.calculateDiscount(500));

2、TypeScript模組

3、TypeScript宣告檔案

TypeScript 作為 JavaScript 的超集,在開發過程中不可避免要引用其他第三方的 JavaScript 的庫。雖然通過直接引用可以呼叫庫的類和方法,但是卻無法使用TypeScript 諸如型別檢查等特性功能。為了解決這個問題,需要將這些庫裡的函式和方法體去掉後只保留匯出型別宣告,而產生了一個描述 JavaScript 庫和模組資訊的宣告檔案。通過引用這個宣告檔案,就可以借用 TypeScript 的各種特性來使用庫檔案了。

假如我們想使用第三方庫,比如 jQuery,我們通常這樣獲取一個 id 是 foo 的元素:

$('#foo');
// 或
jQuery('#foo');

但是在 TypeScript 中,我們並不知道 $ 或 jQuery 是什麼東西:

jQuery('#foo');

// index.ts(1,1): error TS2304: Cannot find name ‘jQuery’.
這時,我們需要使用 declare 關鍵字來定義它的型別,幫助 TypeScript 判斷我們傳入的引數型別對不對:

declare var jQuery: (selector: string) => any;

jQuery('#foo');

declare 定義的型別只會用於編譯時的檢查,編譯結果中會被刪除。

上例的編譯結果是:

jQuery('#foo');

宣告檔案
宣告檔案以 .d.ts 為字尾,例如:

runoob.d.ts

宣告檔案或模組的語法格式如下:

declare module Module_Name {
}

TypeScript 引入宣告檔案語法格式:

/// <reference path = " runoob.d.ts" />

當然,很多流行的第三方庫的宣告檔案不需要我們定義了,比如 jQuery 已經有人幫我們定義好了

例項
以下定義一個第三方庫來演示:

CalcThirdPartyJsLib.js 檔案程式碼:

var Runoob;  
(function(Runoob) {
    var Calc = (function () { 
        function Calc() { 
        } 
    })
    Calc.prototype.doSum = function (limit) {
        var sum = 0; 
 
        for (var i = 0; i <= limit; i++) { 
            sum = sum + i; 
        }
        return sum; 
    }
    Runoob.Calc = Calc; 
    return Calc; 
})(Runoob || (Runoob = {})); 
var test = new Runoob.Calc();

如果我們想在 TypeScript 中引用上面的程式碼,則需要設定宣告檔案 Calc.d.ts,程式碼如下:

Calc.d.ts 檔案程式碼:

declare module Runoob { 
   export class Calc { 
      doSum(limit:number) : number; 
   }
}

宣告檔案不包含實現,它只是型別宣告,把宣告檔案加入到 TypeScript 中:

CalcTest.ts 檔案程式碼:

/// <reference path = "Calc.d.ts" /> 
var obj = new Runoob.Calc(); 
// obj.doSum("Hello"); // 編譯錯誤
console.log(obj.doSum(10));

基礎完結

相關文章