typescript定義函數類型


函數類型

為函數定義類型

給函數定義類型,包括對參數和返回值的類型定義:

function add(arg1: number, arg2: number): number {
  return arg1 + arg2
}

// 箭頭函數
const add = (arg1: number, arg2:number):number => {
  return arg1 + arg2
}

如果這里省略參數的類型,typescript 會默認這個參數是 any 類型;如果省略返回值的類型,那么當函數無返回值時,typescript 默認函數返回值是 void 類型,當函數有返回值時,typescript 會根據我們定義的邏輯推斷出返回值的類型。

 

完整的函數類型

可以定義一個完整的函數類型,它包括參數類型和返回值類型,如下:

// 定義變量 add,指定類型為 (x: number, y: number)=> number
let add:(x: number, y: number)=> number

// 給變量賦值函數,其符合上面定義的函數類型
add = (arg1: number, arg2: number) => arg1 + arg2

可以看到函數類型中的參數名和實際函數的參數名不一致,這里需要注意,只要參數類型是匹配的,那么就認為它是有效的函數類型,而不在乎參數名是否正確。

 

使用接口定義函數類型

使用接口可以清晰地定義函數類型:

interface Add{
  (x: number, y: number): number
}

let add:Add = (arg1: number, arg2: number): number => arg1 + arg2

 

使用類型別名定義函數

類型別名是使用 type 關鍵字定義一個類型,可以用來定義函數類型:

type Add = (x: number, y: number) => number

let add:Add = (arg1: number, arg2: number): number => arg1 + arg2

 

函數參數

可選參數

定義函數類型時,使用 ? 來指定可選參數,但需要注意的是,可選參數必須放在必須參數后面,這跟在接口中定義可選參數不一樣,在定義接口時,可選參數的位置在前在后都無所謂。

// error,x 是可選參數,放在必選參數 y 之前是錯誤的
type Add = (x?: number, y: number) => number

 

默認參數

默認參數與在 es6 中的實現一樣,直接用 = 給出默認值。需要注意兩個地方:一是默認參數的位置不講究,它放在必選參數前后都行;二是當給默認參數指定默認值時,typescript 會識別默認參數的類型,當我們在調用函數時,如果給這個帶默認值的參數傳來別的類型的參數時則會報錯:

let add = (x: number, y = 2) => {
  return x + y
}

add(1, '2') // error,類型“"2"”的參數不能賦給類型“number”的參數

 

可以顯示地給默認參數指定類型:

let add = (x: number, y: number = 2) => {
  return x + y
}

 

剩余參數

對於不知道會傳入多少參數的函數來說,在 javascript 中會使用 arguments 來獲取參數列表。在 typescript 中,使用跟 es6 中一樣的 ... 來將剩余參數收集到一個變量中。

const handleData = (arg1, ...arg2) => {
  console.log(arg2)
}

handleData(1,2,3,4,5,6) // [2,3,4,5,6]

 

給參數指定類型:

const handleData = (arg1: number, ...arg2: number[]) => {
  console.log(arg2)
}

 

函數重載

在一些強類型語言中,函數重載是指定義幾個函數名相同,但參數個數或類型不同的函數,在調用時傳入不同的參數,編譯器會自動調用適合的函數。而在 javascript 中,是沒有函數重載的,我們可以在函數內部判斷參數的個數和類型來指定不同的處理邏輯。

const handleData = (value: any)=>{
  if(typeof value === 'string'){
    return value.split('')
  }else{
    return value.toString().split('').join('_')
  }
}

console.log(handleData('hello')) // ["h", "e", "l", "l", "o"]

console.log(handleData(123)) // 1_2_3

 

我們需要將上面這種情況在類型系統中表示出來。在 typescript 中有函數重載的概念,但不是定義幾個同名實體函數,而是通過為一個函數指定多個函數類型定義,從而對函數調用的返回值進行檢查。代碼如下:

function handleData(value: string): string[]
function handleData(value: number): string
function handleData(value: any):any {
  if(typeof value === 'string'){
    return value.split('')
  }else{
    return value.toString().split('').join('_')
  }
}

console.log(handleData('hello')) // ["h", "e", "l", "l", "o"]

console.log(handleData(123)) // 1_2_3

console.log(handleData(false)) // error,類型“false”的參數不能賦給類型“string”的參數,類型“false”的參數不能賦給類型“number”的參數

首先使用 function 關鍵字定義了兩個同名函數,這兩個函數沒有實際的函數體邏輯,只定義了函數名,參數及參數類型以及函數的返回值類型,這兩個定義稱為 “函數重載”。第三個使用 function 定義的同名函數,是一個完整的實體函數,它不算重載。這三個定義組成一個函數。當函數調用時,會從上到下匹配重載,當匹配不到時會報錯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM