Typescript 函數類型

函數,一等公民(滿滿的自豪感)。javascript

招式一:函數聲明(function declaration)

// function.ts
function sum(x: number, y: number): number {
    return x + y;
}
複製代碼

經過對接口定義的認識,函數的參數多一個和少一個(沒有對參數作可選操做)應該也不行。試一下java

// function2.ts
function sum2(x: number, y: number): number {
    return x + y;
}

sum2(1, 2);

sum2(1, 2, 3);

sum2(1);

// 0.0.6/function2.ts:7:12 - error TS2554: Expected 2 arguments, but got 3.
    // 7 sum2(1, 2, 3);

// 0.0.6/function2.ts:9:1 - error TS2554: Expected 2 arguments, but got 1.
    // 9 sum2(1);
  
// 0.0.6/function2.ts:1:26
    // 1 function sum2(x: number, y: number): number {
    // An argument for 'y' was not provided.
複製代碼

提示很明顯了,就是說咱們參數多了一個,參數少了一個。總結,函數對於參數的個數是不容修改的git

招式二:函數表達式(function expression)

// function3.ts
const sum3 = function(x: number, y: number): number {
    return x + y;
}
複製代碼

從函數表達式的結構分析,= 右邊(→_→)你們都懂的,可是👈左邊咱們發現有點空,是否是得有個類型定義下呢?那又該如何定義?github

// function4.ts
const sum4: (x: number, y: number) => number = function(x: number, y: number): number {
    return x + y;
}
複製代碼

來看 = 左邊,多了 : (x: number, y: number) => number,這裏的 => 不是咱們熟悉的 ES6 箭頭函數中的 =>。Typescript 中的 => 是用來定義函數的,函數左邊是是輸入類型(用 () 括起來),右側是輸出類型。其實,多出的內容也能夠不用手動添加的(晦澀難懂),由於經過賦值操做也能夠將類型推論出來(有種若不自宮亦可成功的意味,哈哈)。typescript

招式三:接口定義(interfaces)

// function5.ts
interface Function5 {
    (x: string, y: string): boolean
}

let function5: Function5 = (x: string, y: string) => {
    return x.search(y) > -1;
}
複製代碼

上面例子是用接口的形式來加持 ES6 的箭頭函數,棒棒的。express

可選參數

這個和上篇接口類型同樣的方式數組

// function6.ts
const showMyName = (firstName: string, lastName?: string): string => {
    if(lastName) {
        return `${firstName}${lastName}`;
    } else {
        return firstName;
    }
}
console.log(showMyName('pr'));
console.log(showMyName('江湖', '再見'));
複製代碼

編譯後ide

// function6.js
var showMyName = function (firstName, lastName) {
    if (lastName) {
        return "" + firstName + lastName;
    }
    else {
        return firstName;
    }
};
console.log(showMyName('pr'));
console.log(showMyName('江湖', '再見'));
複製代碼

問:可選參數後面還能加參數(必選參數)麼?函數

// function7.ts
const showMyName7 = (firstName?: string, lastName: string): string => {
    if(firstName) {
        return `${firstName}${lastName}`;
    } else {
        return lastName;
    }
}

// 0.0.6/function7.ts:1:42 - error TS1016: A required parameter cannot follow an optional parameter.
    // 1 const showMyName7 = (firstName?: string, lastName: string): string => {
複製代碼

報錯的緣由是可選參數後面不能再放參數(必選)post

剩餘參數

咱們知道 ES6 有 rest 參數(形式是 ...rest ), 用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。那 Typescript 中的 rest 是否也是如此呢?

// function8.ts
// function8.ts
const push = (array: any[], ...rest: any[]) => {
    rest.forEach(r => {
        array.push(r);
    });
}

let arr = [false];
push(arr, '1', 2, 3);

const push1 = (array: any[], ...rest: any[], x: number) => {
    rest.forEach(r => {
        array.push(r);
    });
    rest.push(x);
}

// 0.0.6/function8.ts:11:30 - error TS1014: A rest parameter must be last in a parameter list.
    // 11 const push1 = (array: any[], ...rest: any[], x: number) => {
複製代碼

參數 array..rest 咱們都定義了類型,...rest 其實就是一個數組。另外,剩餘參數和可選參數後面都不能再有參數

默認值

ES6 中有給函數參數添加默認值的操做,那 Typescript 若是也有此等操做,那是怎樣的?設置默認值的參數能夠再有參數麼(是否是被不能再有參數嚇怕了)?

// function9.ts
const showMyNameAgain = (firstName: string = 'pr', lastName?: string, ...rest: any[]): string => {
    let tmp: string = '';
    if(rest.length) {
        tmp = rest.join(' ');
    }
    if(lastName) {
        return `${firstName}${lastName}${tmp}`;
    } else {
        return `${firstName}${tmp}`;
    }
}

console.log(showMyNameAgain());
console.log(showMyNameAgain('胖芮',',男', '今年', 30));
複製代碼

編譯後

// function9.js
var showMyNameAgain = function (firstName, lastName) {
    if (firstName === void 0) { firstName = 'pr'; }
    var rest = [];
    for (var _i = 2; _i < arguments.length; _i++) {
        rest[_i - 2] = arguments[_i];
    }
    var tmp = '';
    if (rest.length) {
        tmp = rest.join(' ');
    }
    if (lastName) {
        return "" + firstName + lastName + tmp;
    }
    else {
        return "" + firstName + tmp;
    }
};
console.log(showMyNameAgain()); // pr
console.log(showMyNameAgain('胖芮', ',男', '今年', 30)); // 胖芮,男今年 30
複製代碼

經過上面例子可見,默認值與 ES6 賦值方式無異。同時,咱們發現剩餘參數可放在可選參數後

重載

重載的意思不是從新載入,這兒不可望文生義。實際意思是根據不一樣數量或類型的參數,作出不一樣的處理。

好比有這個一個場景:傳入數字就乘以10並返回數字,傳入字符串就在它前面加上 hello並返回字符串。

咱們先分析下注意點

  • 輸出值類型需同輸入參數類型一致(用到聯合類型);
  • 根據參數類型作不一樣操做處理(用到類型判斷);
// function10.ts
const chongzai = (x: number | string): number | string => {
    if(typeof x === 'string') {
        return `hello, ${x}`;
    } else if (typeof x === 'number') {
        return x * 10;
    }
}
複製代碼

以上例子這麼寫沒有問題,但是,有一點彷佛沒嚴格約束就是第一點(輸出值類型需同輸入參數類型一致(用到聯合類型)),上面代碼 return x * 10; 改成 x * 10 + ''; 也不會報錯,可是並不符合咱們的要求。因此得手動給函數定義類型

// function11.ts
function chongzai2(x: string): string;
function chongzai2(x: number): number;
function chongzai2(x: number | string): number | string {
    if(typeof x === 'string') {
        return `hello, ${x}`;
    } else if (typeof x === 'number') {
        return x * 10;
    }
}
複製代碼

咋一看,怎麼函數 chongzai2 聲明瞭 3 次。其實否則,前 2 次是函數定義,第 3 次是函數實現。

本次代碼 Github

你能夠...

上一篇:Typescript 數組類型

下一篇:Typescript 內置對象

目錄:Typescript 小書之入門篇

相關文章
相關標籤/搜索