iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

Hello TypeScript 菜鳥系列 第 14

Day 13. TypeScript Function 函式

  • 分享至 

  • xImage
  •  

Day 13 終於來到函式(function),函式篇章也不會太難,只是有一些觀念要留意。


函式

在TypeScript裡,要替函式加上型別的語法如下:

function name(para1: type, para2: type): returnType{
	// ...
}

事實上,TypeScript compiler也能自行推導函式回傳值型別,例如以下函式:

function sum(num1: number, num2:number) {
	returm num1 + num2;
}

在這個比較簡單的加總函式裡,回傳值型別會自動被推導成 number 型別。不過要注意的是,如果回傳型別比較複雜,可能是好幾個型別合併的型別,回傳型別就有可能被推倒成 Unionany。如果想避免被推導成 any 型別,建議還是明確寫出回傳值的型別。

另外之前在講TypeScript基本型別有一個是 void,也就是明確指明函式沒有回傳值或回傳 undefined

function pring(message: string): void {
	console.log(message);
}

Optional parameters

如果函式有參數(parameter),則TypeScript會檢查使用函式所代入的引數(argument)數量和型別是否符合所定義函式的參數數量和型別:

function sum (num1: number, num2: number, num3: number): number {
	return num1 + num2 + num3;
}

console.log(sum(1, 2));	// error

如果想解決部分參數其實是非必要參數的問題,就可以使用optional parameter(中文不確定怎麼解釋)。如同前幾篇所說,只要提到 optional 就會想到要用的符號就是 ?

function sum (num1: number, num2: number, num3?: number): number {
	if(typeof num3 !== 'undefined'){
		return num1 + num2 + num3;
	}
	return num1 + num2;

}

sum(1, 2);	// 3

這裡唯一要留意的是,如果參數是optional parameter,則必須放在不是optional parameters的參數後面


Default parameters 預設參數

optional parameter第一個範例因為沒有指定optional parameter所以出現了錯誤,而這樣的錯誤其實也可以用預設參數(default parameter)去避免:

function sum (num1: number, num2: number, num3: number = 0): number {
	return num1 + num2 + num3;
}

console.log(sum(1, 2));	// 3

在這個範例裡,因為第三個參數有給定預設值為0,所以在使用 sum(1, 2) 呼叫函式時,回傳的東西就相當於 return 1 + 2 + 0;

不過和 optional parameter 不同的是:

  1. 預設參數不一定要在必要參數的後面;
  2. 如果預設參數放在必要參數之前且要使用預設值,可以輸入 undefined當作預設參數的引數。

第2個要點的意思如下:

function sum (num1: number = 0, num2: number, num3: number): number {
	return num1 + num2 + num3;	// 等價於 0 + 1 + 2
}

console.log(sum(1, 2));	// 3

Rest parameters 不定參數

有時候我們不確定要輸入的參數數量,這時可以使用不定參數(rest parameters),跟JavaScript一樣,一個函式只能有一個不定參數並且必須是最後一個參數。若要在TypeScript使用不訂參數,可以指定不定參數的型別為陣列:

function sum (...rest: number[]): number {
	let sum = 0;
	rest.forEach(num => sum+= num);
	return sum;
}

console.log(sum(1, 2, 3, 4, 5));	// 15

Overloading function

JavaScript本身是沒有Overloads的概念,如果有兩個同名函式,由上往下依序讀取JavaScript檔案的話,下面的函式會覆蓋掉上面寫的函式。

但在TypeScript語法裡,我們可以寫出類似其他語言的Overloading functions,不過TypeScript的overloads和其他語言的overloads概念是不同的。

TypeScript的overloads主要是為了建立函式參數型別和回傳值型別之間的關聯,這邊使用TypeScript Tutorial的overloads舉例:

// TypeScript
function add(input1: number | string, input2: number | string): number | string {
	if(typeof input1 === 'number' && typeof input2 === 'number'){
		return input1 + input2;
	}
	if(typeof input1 === 'string' && typeof input2 === 'string'){
		return input1 + input2;
	}
}

我們知道兩個 number 型的數值可以用 + 相加;兩個 string 型的值可以用 + 串接,但即使加入判斷參數型別的程式碼,其實也無法保證回傳值的型別是 number 還是 string,這個時候就能用TypeScript的overloading function語法:

function add(input1: number, input2: number): number;
function add(input1: string, input2: string): string;
function add(input1: any, input2: any): any {
		return input1 + input2;
}

從這邊就可以看出不同型別的輸入參數都有相同型別的回傳值,只是使用overloading function要有相同數量的參數,否則就要使用optional parameter:

function add(input1: number, input2: number): number;

function add(input1: string, input2: string): string;
function add(input1: number, input2: number, input3?: number): number{
	if(input3){
		return input1 + input2 + input3;
	}
	return input1 + input2;
}

此外,class語法裡的function,即method,也支援overloading function,若有需要就可以將method寫成overloads的形式。

今天function的淺談就到這裡,明天開始會認識比較重要的語法,像是 classinterfacegeneric 等,若有時間也會加入怎麼在React裡用TypeScript。


參考資料
TypeScript Tutorial
TypeScript for JavaScript Programmers
Function Overloading in JavaScript


上一篇
Day 12. [複習] 程式控制:迴圈(Loop)
下一篇
Day 14. TypeScript Class 類別:基本語法
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言