# 5. 函数的类型、接口与类数组

主要介绍函数类型、用接口表示数组、类数组

# 函数的类型

在JS中,有两种定义函数的方式:

  1. 函数声明(Function declaration)
  2. 函数表达式(Function expression)
// 函数声明
function sum(x, y) {
  return x + y
}
// 函数表达式
let mySum = function(x, y) {
  return x + y
}

# ts函数声明

对函数的参数,返回值进行约束,参数多或少都是不允许的

function sum(x: number, y: number): number {
  return x + y
}
sum(1, 2)
sum(1, 2, 3) // Error
sum(1) // Error

# ts函数表达式

let mySum = function (x: number, y: number): number {
  return x + y
}
// 规范写法 ts的类型定义中,=> 用来表示函数的定义,左边是输入类型、需要用括号括起来,右边是输出类型
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
  return x + y
}

# 用接口定义函数形状

interface SearchFunc {
  // 接口里面的函数类型
  (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  return source.includes(subString)
}

# 可选参数

函数的可选参数必须要在必选参数后面,如果可选参数放前面,会提示错误

function buildName(firstName: string, lastName?: string) {
  return lastName ? `${firstName} ${lastName}` : firstName
}
let tomcat = buildName('Tom', 'Shu');
let tom = buildName('Tom');

# 参数默认值

如果指定了默认参数,该参数即成为可选参数,且没有可选参数位置的限制

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

# 剩余参数

与es6一样,剩余参数只能是最后一个参数

function push(array, ...items) {
  items.forEach(item => array.push(item))
}
let a = []
push(a, 1, 2, 3) // items [1, 2, 3]

// typescript 约束 
function push(array: any[], ...items: any[]) {
  items.forEach(item => array.push(item))
}

# 重载

函数重载是指允许同时定义几个名称相同的函数(但参数个数、类型、返回值可能会不一样),一般js里后面定义的函数会直接覆盖前面的函数

例子:实现一个函数reverse,输入数字123时,输出321,输入字符串'hello'时,输出反转字符串 'olleh'

// 普通联合类型实现
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函数
// 前两次是函数定义,最后一次是函数实现。ts会优先匹配最前面的,再匹配的后面的
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('')
  }
}

# 用接口表示数组

NumberArray 表示:只要索引的类型是数字时,那么值的类型必须是数字。除了类数组外,一般都不使用这种方式

interface NumberArray {
  [index: number]: number
}
let array: NumberArrray = [1, 1, 2, 3, 5]

# 类数组

类数组不是数组类型,需要用接口来描述类数组

// arguments 实际是一个类数组,但赋值给数组类型的变量会报错
function sum() {
  let args: number[] = arguments // Error 
}

// 用接口来描述类数组
function sum() {
  let args: {
    [index: number]: number;
    length: number;
    callee: Function;
  } = arguments
}

interface IArguments {
  [index: number]: number;
  length: number;
  callee: Function;
}

function sum() {
  let args: IArguments = arguments;
}
上次更新: 2022/12/19 02:18:42