Typescript函数

函数定义的两种方式

  • 函数关键字
function add(x: number, y: number): number {
  return x + y;
}
  • 函数表达式
let add = function (x: number, y: number): number {
  return x + y;
}

函数类型

在ts中函数类型指的是函数参数及返回值的类型

  • 完整的函数类型
let foo: (x: string, y:string) => string = function(a:string, b:string) {
  return a + b
}

函数类型的等号左边可以理解为函数签名,等号右边为函数实现

  • 类型推断
    当函数的具体实现没有定义参数及返回值类型时,可以根据等号左边的类型定义推断出类型,下面的例子推断出a:string,b:string,返回值类型为string
let bar: (x:string , y:string) => string = function(a, b) {
  return a + b
}
bar(1, 'bar')  //error 类型“1”的参数不能赋给类型“string”的参数

可选参数和默认参数

在js中函数的参数可以按照定义传参,也可以多传或者不传

function foo(arg1, arg2) {
  // do nothing
  return 
}
foo() // ok arg1 === undefined arg2 === undefined
foo(1,2) // ok
foo(1,2,3)

但在ts中,类型检查器会严格检查参数类型以及参数个数,这意味着你在参数类型正确的前提下不能多传或者少传参数。

function buildName(firstName: string, lastName: string) {
  return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // error, An argument for 'lastName' was not provided.
let result2 = buildName("Bob", "Adams", "Sr.");  // error, 应有 2 个参数,但获得 3 个。
let result3 = buildName("Bob", "Adams");         // ah, just right

在ts中,函数参数定义时,可以使用可选参数,一般最佳实践是可选参数放在所有必传参数的后面,除了可选参数还有默认参数,及参数具有默认值。默认参数对顺序没有要求。

let fooBar:(f:string, b?:string) => void = 
function(foo, bar = 'bar') {
  console.log(foo + '-' + bar)
}

fooBar('foo', undefined)  //foo-bar
fooBar('foo') // foo-bar

上面的例子将函数可选参数和默认参数结合使用,值得注意的是,如果默认参数在必须参数前,要想函数使用默认值必须明确传入undefined值,否则只传必须参数会抛出异常

function buildName(firstName = "Will", lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // error, too few parameters

剩余参数

使用...展开剩余参数,这es6剩余参数的行为一致

function joinStr(s1:string, ...str:String[]):string {
  return s1.concat('-').concat(str.join('-'))
}
console.log(joinStr('a',...['b','c','d']))   //a-b-c-d

其他

this
ts中this也是有类型的,所以在使用函数时,需要注意this类型,常见的两种this类型定义,一种方式是定义为某个具体类型,另一种就是this:void。否则在编辑器设置了–noImplicitThis标记时, 它会指出 this的类型为any这个错误。

interface Card {
    suit: string;
    card: number;
}
interface Deck {
    suits: string[];
    cards: number[];
    createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    // NOTE: The function now explicitly specifies that its callee must be of type Deck
    createCardPicker: function(this: Deck) {
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);
interface UIElement {
    addClickListener(onclick: (this: void, e: Event) => void): void;
}

class Handler {
    info: string;
    onClickGood(this: void, e: Event) {
        // can't use this here because it's of type void!
        console.log('clicked!');
    }
}
let h = new Handler();
uiElement.addClickListener(h.onClickGood);

重载

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

上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面.

脑图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值