《三》TypeScript 中函数的类型

TypeScript 允许指定函数的参数和返回值的类型。

  1. 函数声明的类型定义:function 函数名(形参: 形参类型, 形参: 形参类型, ...): 返回值类型 {}

    function sum(x: number, y: number): number {
        return x + y
    }
    sum(1, 2) // 正确
    sum(1, 2, 3) // 错误。输入多余的或者少于要求的参数,都是不被允许的
    
  2. 函数表达式的类型定义:const 函数名: (形参: 形参类型, 形参: 形参类型, ...) => 返回值类型 = function () {}

    对函数本身进行类型声明:(形参: 形参类型, 形参: 形参类型, ...) => 返回值类型
    对没有参数和没有返回值的函数本身进行类型声明:() => void

    // 不规范的写法。可以通过编译,但事实上只是对等号右侧的匿名函数进行了类型定义,而等号左边 sum 是赋值操作后进行类型推论而推断出来的,并没有对 sum 函数本身进行类型声明
    const sum = function (x: number, y: number): number {
        return x + y
    }
    
    // 规范的写法。在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
    const sum: (x: number, y: number) => number = function (x: number, y: number): number {
        return x + y
    }
    
    // 规范的写法还可以进行一些省略。在函数引用中定义好了函数的参数类型和返回值类型,那么函数体可以省略,不需要再次指定类型
    const sum: (x: number, y: number) => number = function (x, y) {
        return x + y
    }
    
  3. 函数的调用签名(Call Signatures):函数除了作为函数本身可以被调用外,还可以作为对象有属性和方法。但是,函数声明的类型定义和函数表达式的类型定义并不支持声明属性和方法,此时可以使用函数的调用签名。

    
    // 函数的调用签名的写法:可以用 Type,也可以用 interface
    type sumType = {
      // 对函数作为对象的属性值和方法的类型定义
      name: string,
      // 对函数作为函数本身的类型定义。写法为 (参数列表): 返回值类型
      (x: number, y: number): number,
    }
    
    const sum: sumType = function (x: number, y: number): number {
      return x + y
    }
    sum.name = 'sumFunc'
    sum(1, 2)
    
  4. 函数的构造签名:函数除了可以直接调用外,还可以使用 new 操作符调用。当通过 new 操作符调用时,TypeScript 就会认为这个函数是一个构造函数,会产生一个实例对象。此时,可以使用函数的构造签名,方法是在调用签名前面加一个 new 关键词。

    对函数进行普通的函数类型定义,也可以使用 new 操作符来调用。但是,TypeScript 类型推断出来的实例对象的类型是 any。
    《三》TypeScript 中函数的类型_第1张图片

    class Person {}
    
    type PersonType = {
      new (): Person,
    }
    
    function factory(callback: PersonType) {
      const p = new callback()
      return p
    }
    factory(Person)
    

    《三》TypeScript 中函数的类型_第2张图片

函数可选参数的类型定义:

可以用 ? 表示可选的参数,可选参数必须放在最后面。

function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + ' ' + lastName
    } else {
        return firstName
    }
}
let tomcat = buildName('Tom', 'Cat') // 正确
let tom = buildName('Tom') // 正确

在 ES6 中,允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数,但此时不受可选参数必须放在最后面的限制。

function buildName(firstName: string = 'Tom', lastName: string) {
    return firstName + ' ' + lastName
}
let tomcat = buildName('Tom', 'Cat') // 正确
let cat = buildName(undefined, 'Cat') // 正确

函数重载的类型定义:

重载就是根据参数,选择相同函数名而参数不同的函数。严格来说,JS 中其实是没有函数重载的概念的。

在 TypeScript 中,可以去编写不同的重载签名来表示函数可以以不同的方式进行调用。一般是编写两个或者两个以上的重载签名,再去编写一个通用的函数实现。

// 实现函数接收两个参数,返回相加后的值。只能同时是数字,返回数字;或者同时是字符串,返回字符串
// 1. 先编写函数的重载签名:是没有实现体的
function add(arg1:number, arg2: number): number
function add(arg1:string, arg2: string): string
// 2. 然后编写通用的函数实现:是有实现体的
function add(arg1, arg2) {
  return arg1 + arg2
}

// 3. 在调用函数的时候,会根据传入的参数类型来决定执行函数体时,执行哪一个函数的重载签名
add(10, 20) // 正确
add('Hello', 'World') // 正确
add(10, 'World) // 错误。调用的是函数的重载签名,通用函数不能被调用

你可能感兴趣的:(TypeScript,TypeScript)