zoukankan      html  css  js  c++  java
  • typeScript-函数的类型

    函数的类型

    函数声明

    在JavaScript中,有两种常见的定义函数的方式——函数声明(Function Declaration) 和函数表达式(Function Expression)

    // 函数声明
    function sum (x,y) {
      return x + y
    }
    // 函数表达式
    let sum = function (x,y) {
      return x +y
    }
    

    一个函数有输入和输出,要在typeScript中对其约束,需要把输入输出都考虑到,其中函数声明的类型比较简单

     function mySum (x:number,y:number) :number{
        return x + y
      }
    

    注意输入多余或者小于多余的参数是不允许的,会报错

    function mySum (x:number,y:number) :number{
        return x + y
      }
      mySum(1)
    // ERROR in 
    //  TS2554: Expected 2 arguments, but got 1.
    
    
     function mySum (x:number,y:number) :number{
        return x + y
      }
      mySum(1,2,3)
    // ERROR in 
    // TS2554: Expected 2 arguments, but got 3.
    
    

    函数表达式

    如果现在我们写一个对函数表达式的定义,可能会写成这样

    let mySum1 = function (x:number,y:number):number {
        return x + y
      }
    

    这是可以通过编译的,不过事实上,上面的代码只对等号右边的匿名函数进行了类型定义,而等号左边的mySum1是通过赋值操作类型推论而推断出来的,如果需要我们手动给mySum1添加类型,则应该是这样的

    let mySum1 : (x:number,y:number)=>number = function (x:number,y:number):number {
        return x + y
      }
    

    注意不要混淆了typeScript中的=>和es6中的=>,在typeScript类型定义中=>是用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。早es6中=>表示箭头函数

    用接口定义函数的形状

    我们也可以使用接口的方式来定义一个函数更符合的形状

    let mySearch:SearchFunc;
      mySearch = function (source:string,subString:string) {
        return source.search(subString) !== -1
      }
    

    采用函数表达式接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数赋值时保证参数个数,参数类型,返回值类型不变。

    可选参数

    前面提到,输入多余(或少于要求的)参数是不允许的,那么如何定义可选参数呢,与接口中的可选属性类似,我们使用?表示可选参数

    function buildName(firstName:string,lastName?:string) {
        if(lastName) {
          return firstName + ' ' + lastName
        } else {
          return firstName
        }
      }
      let tomcat = buildName('Tom','cat')
      let tom = buildName('Tom')
      console.log(tomcat, tom)
    

    需要注意的是,可选参数必须杰仔必须参数后面。换句话说,可选参数后面不能再跟必须参数

    function buildName1 (firstName?:string,lastName:string) {
        if (firstName) {
          return firstName + ' ' + lastName
        } else {
          return lastName
        }
        let lilyCat = buildName1('lily','cat')
        let cat = buildName1(undefined,'cat')
    // ERROR in 
    // TS1016: A required parameter cannot follow an optional parameter.
    

    参数默认值

    在ES6中,允许给函数的参数添加默认值,typeScript会将添加默认值的参数识别为可选参数

    function  buildName2(firstName:string,lastName:string = 'Cat') {
        return firstName + ' ' + lastName
      }
      const makaCat = buildName2('maka')
      const makaCat1 = buildName2('maka','cat1')
      console.log(makaCat,makaCat1)
    

    此时就不受可选参数必须在必须参数的后面的限制了

      function buildName3(firstName:string='Tom',lastName:string) {
        return firstName + ' ' + lastName
      }
      console.log(buildName3(undefined,'ksd'))
    

    剩余参数

    ES6中,可以使用...rest的方式来获取函数中的剩余参数(rest参数)

    function push (array,...items) {
        items.forEach(function (item) {
          array.push(item)
        })
        return array
      }
      let a:any[] = []
      console.log(push(a,1,2,3))
    

    事实上,items是一个数组,我们可以用数组的类型来定义它

     function push2(array:any[],...items:any[]) {
        items.forEach((function (item) {
          array.push(item)
        }))
        return array
      }
      console.log(push2([],3,4,5))
    

    注意,rest参数只能是最后一个参数

    重载

    重载允许一个函数接受不同数量或类型的参数时,做不同的处理

    比如,我们需要一个reverse函数,当输入数字的123,输出反转数字321,当输出字符串'hello'时候,输出反转的字符串 'olleh'。

     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('')
        }
      }
      console.log(reverse(123),reverse('hello'))// '321' 'olleh'
    

    然后,这样有一个缺点就是不能精确的表达,输入数字的时候,输出也为数字,输入为字符串的时候,输出也为字符串

    这时,我们可以用重载定义多个reverse的函数类型

     function reverse1(x:number):number;
      function reverse1(x:string):string;
      function reverse1(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('')
        }
      }
      console.log(reverse1(123),reverse1('world'))
    

    上例中,我们重复定义了多次函数reverse1,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。

    注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/dehenliu/p/14972772.html
Copyright © 2011-2022 走看看