本篇將介紹在TypeScript里如何定義和使用方法。
一、方法標准聲明和使用
1 // 方法聲明 2 function func(x: number, y: number): number { 3 return x + y; 4 }
在TypeScript里,方法聲明可以明確定義每一個參數的類型,和返回值的類型。在編譯時,編譯器會檢查方法體的返回值類型是否符合定義的類型,同時在調用的時候也會檢查傳入的參數類型是否符合定義的類型,參數個數是否符合定義的個數。
1 let result1 = func(1, 2); // 正確的調用方式。 2 let result2 = func_lambda(1, 2, 3); // 錯誤的調用方式。參數個數多余定義。 3 let result3 = func_lambda(1); // 錯誤的調用方式。參數個數少於定義。 4 let result4 = func_lambda('1', '2'); // 錯誤的調用方式。參數類型不符合定義。
另外,方法聲明也支持使用Lambda表達式。
1 // lambda表達式聲明 2 let func_lambda: (x: number, y: number) => number = function (x, y) { return x + y };
二、缺省參數聲明
在某些情況下,方法調用只需要傳入部分參數。TypeScript也支持缺省參數的聲明方式。
1 // 缺省參數定義 2 let showName = function (firstName: string, lastName?: string): string { 3 if (lastName) { 4 return firstName + ' ' + lastName; 5 } else { 6 return firstName; 7 } 8 }; 9 10 let wholeName1 = showName('星辰', 'Lee'); 11 let wholeName2 = showName('星辰');
通過在參數名稱后面加上?,標識該參數是缺省的,調用時如果對應參數位置不傳入,對應參數位置則為undefined。
三、默認值參數聲明
在某些情況下,方法調用時某些參數在不傳入時,默認使用方法定義的值。TypeScript同樣支持默認值參數的聲明方式。
1 // 默認值參數定義 2 let showName2 = function (firstName: string, lastName = 'Lee'): string { 3 return firstName + ' ' + lastName; 4 }; 5 6 let wholeName3 = showName2('星辰');
通過在參數名稱后加上=號並賦值,標識該參數具有默認值。調用時如果對應參數位置不傳入或者傳入undefined,則取默認值,否則取對應位置傳入的值。
四、多參數聲明
像其他強類型語言一樣,TypeScript在定義方法的時候,也支持不明數量的多參數傳入。
1 // 多參數定義 2 let restParamsFunc = function (param1: string, ...restParams: string[]): string { 3 return param1 + ' ' + restParams.join(' '); 4 }; 5 6 let resParamsFuncResult = restParamsFunc('a', 'b', 'c');
通過在參入名稱前加上...(三個小數點),標識對應位置的參數可以傳入多個。因為參數類型已明確定義,所以傳入的多個參數的類型必須與定義保持一致,否則編譯時將提示錯誤。
五、其他類型參數聲明
對象類型:
1 // 對象類型參數 2 let jsonParamFunc = function (x: { p1: string }): string { 3 return x.p1; 4 }; 5 6 let jsonParamFuncResult1 = jsonParamFunc({ p1: 'a' }); // 賦值類型正確 7 let jsonParamFuncResult2 = jsonParamFunc({ p1: 'a', p2: 'b' }); // 賦值類型錯誤,參數屬性比定義的多。 8 let jsonParamFuncResult3 = jsonParamFunc({ p3: 'c' }); // 復制類型錯誤,參數屬性名不匹配。 9 let params = { p1: 'a', p2: 'b' }; 10 let jsonParamFuncResult4 = jsonParamFunc(params); // 用變量代替直接復制,編譯器檢查通過。
上面的例子里,參數類型被定義為一個擁有屬性“p1”的json對象。在方法調用時,傳入的參數將嚴格符合參數類型的定義,參數對象的屬性多余或者少於定義將提示錯誤,屬性名稱與定義不一致也將提示錯誤。
但是,如果傳入的是一個變量,變量的屬性只要能滿足定義的類型屬性即可。
方法類型:
1 // 方法類型參數 2 let funcParamFunc = function (func: (x: string, y: string) => string): string { 3 let _x = 'a'; 4 let _y = 'b'; 5 return func(_x, _y); 6 }; 7 8 let funParamFuncResult = funcParamFunc(function (x, y) { return x + y });
方法參數類型可定義為一個固定結構的方法,該方法就成為了一個回調方法。
六、方法重載
TypeScript也支持方法重載。
1 // 方法重載 2 function overloadFunc(x: { p1: string }): string; 3 function overloadFunc(x: number): number; 4 function overloadFunc(x): any { 5 if (typeof x == 'object') { 6 return x.p1; 7 } 8 9 if (typeof x == 'number') { 10 return x; 11 } 12 } 13 14 let overloadFuncResult1 = overloadFunc({ p1: 'a' }); 15 let overloadFuncResult2 = overloadFunc(1);
在上面的例子里,連續聲明了擁有同一個名稱的三個方法:
前兩個方法只有方法定義,沒有方法體。它們定義了重載方法的個數和表現形式。
最后一個方法的參數沒有定義類型,返回值定義為any,同時有方法體。它定義了重載方法的具體實現。
最后,將以上代碼編譯過后的JavaScript代碼展示出來,可以進行對比。
1 // 方法聲明 2 function func(x, y) { 3 return x + y; 4 } 5 var result1 = func(1, 2); // 正確的調用方式。 6 var result2 = func_lambda(1, 2, 3); // 錯誤的調用方式。參數個數多余定義。 7 var result3 = func_lambda(1); // 錯誤的調用方式。參數個數少於定義。 8 var result4 = func_lambda('1', '2'); // 錯誤的調用方式。參數類型不符合定義。 9 // lambda表達式聲明 10 var func_lambda = function (x, y) { return x + y; }; 11 // 缺省參數定義 12 var showName = function (firstName, lastName) { 13 if (lastName) { 14 return firstName + ' ' + lastName; 15 } 16 else { 17 return firstName; 18 } 19 }; 20 var wholeName1 = showName('星辰', 'Lee'); 21 var wholeName2 = showName('星辰'); 22 // 默認值參數定義 23 var showName2 = function (firstName, lastName) { 24 if (lastName === void 0) { lastName = 'Lee'; } 25 return firstName + ' ' + lastName; 26 }; 27 var wholeName3 = showName2('星辰'); 28 // 多參數定義 29 var restParamsFunc = function (param1) { 30 var restParams = []; 31 for (var _i = 1; _i < arguments.length; _i++) { 32 restParams[_i - 1] = arguments[_i]; 33 } 34 return param1 + ' ' + restParams.join(' '); 35 }; 36 var resParamsFuncResult = restParamsFunc('a', 'b', 'c'); 37 // 對象類型參數 38 var jsonParamFunc = function (x) { 39 return x.p1; 40 }; 41 var jsonParamFuncResult1 = jsonParamFunc({ p1: 'a' }); // 賦值類型正確 42 var jsonParamFuncResult2 = jsonParamFunc({ p1: 'a', p2: 'b' }); // 賦值類型錯誤,參數屬性比定義的多。 43 var jsonParamFuncResult3 = jsonParamFunc({ p3: 'c' }); // 復制類型錯誤,參數屬性名不匹配。 44 var params = { p1: 'a', p2: 'b' }; 45 var jsonParamFuncResult4 = jsonParamFunc(params); // 用變量代替直接復制,編譯器檢查通過。 46 // 方法類型參數 47 var funcParamFunc = function (func) { 48 var _x = 'a'; 49 var _y = 'b'; 50 return func(_x, _y); 51 }; 52 var funParamFuncResult = funcParamFunc(function (x, y) { return x + y; }); 53 function overloadFunc(x) { 54 if (typeof x == 'object') { 55 return x.p1; 56 } 57 if (typeof x == 'number') { 58 return x; 59 } 60 } 61 var overloadFuncResult1 = overloadFunc({ p1: 'a' }); 62 var overloadFuncResult2 = overloadFunc(1);