天天看點

ts 函數的類型

//在 JavaScript 中,有兩種常見的定義函數的方式——函數聲明(Function Declaration)和函數表達式(Function Expression):
// 函數聲明(Function Declaration)
function sum(x, y) {
    return x + y;
}

// 函數表達式(Function Expression)
let mySum = function (x, y) {
    return x + y;
};

      
// 函數聲明(Function Declaration)方式函數的類型      
function sum(x: number, y: number): number {
    return x + y;
}

//如果要我們現在寫一個對函數表達式(Function Expression)的定義,可能會寫成這樣:
           
let mySum = function (x: number, y: number): number {
    return x + y;
};                

//這是可以通過編譯的,不過事實上,上面的代碼隻對等号右側的匿名函數進行了類型定義,而等号左邊的          mySum                ,是通過指派操作進行類型推論而推斷出來的。
//如果需要我們手動給          mySum                 添加類型,則應該是這樣:      
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};           
//在 TypeScript 的類型定義中,         =>                 用來表示函數的定義,左邊是輸入類型,需要用括号括起來,右邊是輸出類型。

//我們也可以使用接口的方式來定義一個函數需要符合的形狀
      
interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}                
//采用函數表達式|接口定義函數的方式時,對等号左側進行類型限制,可以保證以後對函數名指派時保證參數個數、參數類型、傳回值類型不變。

//前面提到,輸入多餘的(或者少于要求的)參數,是不允許的。那麼如何定義可選的參數呢?與接口中的可選屬性類似,我們用          ?                 表示可選的參數
//需要注意的是,可選參數必須接在必需參數後面。換句話說,可選參數後面不允許再出現必需參數了

//在 ES6 中,我們允許給函數的參數添加預設值,TypeScript 會将添加了預設值的參數識别為可選參數
//此時就不受「可選參數必須接在必需參數後面」的限制了      
//當可選參數在必需參數前面,傳參數時是沒法忽略第一個參數而直接給         lastName傳值的,此時,必須對一個參數指派undefined,觸發第一個參數等于預設值,null是沒有這個效果的           
function buildName(firstName: string = 'Tom', lastName: string) {
    return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName(undefined, 'Cat');           
//重載
//利用聯合類型,我們可以這麼實作:
      
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}           

 //然而這樣有一個缺點,就是不能夠精确的表達,輸入為數字的時候,輸出也應該為數字,輸入為字元串的時候,輸出也應該為字元串。這時,我們可以使用重載定義多個 

reverse

 的函數類型:

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}