Skip to content

TypeScript 函数

TypeScript 函数

函数定义

在 JS 中定义函数分为两种方式: 声明式 , 表达式定义,那么在 TypeScript 中也分别提供了基于这两种方式去约束函数的方法

函数声明式

js
//  : number 定义了函数的返回值为number类型
function func(a: number, b: number): number {
  return a + b
}
// (a: number, b: number) => number 定义了函数的入参和出参
// function(a: number, b: number) {} 定义了函数的内容
const func1: (a: number, b: number) => number = function (a: number, b: number) {
  return a + b
}

表达式

js
//  : number 定义了函数的返回值为number类型
const fun1 = (a: number, b: number): number => a + b

// 函数声明式第二种定义方式
const func1: (a: number, b: number) => number = (a: number, b: number) => a + b

image-20230214154020666

type 定义函数

js
// type去定义一个函数
type Fun1 = (a: number, b: number) => number

const fun1: Fun1 = (a, b) => a + b

interface 定义函数

js
// interface 去定义一个函数
interface Fun1 {
  (a: number, b: number): number;
}

const fun1: Fun1 = (a, b) => a + b

函数参数

可选参数

es5 里面方法的实参和行参可以不一样,但是 ts 中必须一样,如果不一样就需要在可选参数后加?,这就是可选参数。

js
function fetch(url: string, id?: number): string {
  if (id === undefined) {
    return `使用默认ID获取数据`
  } else {
    return `id = ${id}`
  }
}

// 注意: 可选参数必须配置到参数的最后面

// 错误写法:可选参数不在最后面
// function electParam2(name?: string, age: number): string {
//     ...
// }

注意

  1. 可选参数必须在其他参数后面,可以有多个
js
// 错误的写法:可选参数不在最后面
function add(a?: number, b: number): number {}
js
// 可选参数多个
// 这时候需要注意的是:先有b,才有c
// add(1,2)    // a=1; b=2; c=undefined
// add(1,2,3)  // a=1; b=2; c= 3
function add(a: number, b?: number, c?: number): number {}

默认参数

es5 里面没法设置默认参数,es6 和 ts 中都可以设置默认参数

对于简单类型 我们可以直接使用 属性:类型 = 默认值的方式

js
// 对于简单类型 我们可以直接使用 `属性:类型 = 默认值`的方式 。
//
// 2. 可选类型不能使用默认参数
function add(a: number = 1, b?: number): number {}
  1. 其实这时候类型我们可以省略,TS 会默认进行类型推导 , 上述可以省略为 function add(a = 1, b?: number): number {}

  2. 可选类型不能使用默认参数(可选参数代表参数可以为 undefined , 默认参数为:参数为 undefined 的时候默认赋值为默认参数,相悖)

错误栗子: function add(a = 1, b?: number = 2): number {}

注意

  1. 可选参数必须在其他参数后面,可以有多个
js
// 错误的写法:可选参数不在最后面
function add(a?: number, b: number): number {}
js
// 可选参数多个
// 这时候需要注意的是:先有b,才有c
// add(1,2)    // a=1; b=2; c=undefined
// add(1,2,3)  // a=1; b=2; c= 3
function add(a: number, b?: number, c?: number): number {}

剩余参数

借助于 ES6 的三点运算符,其具体规则可以看 三点运算符, TypeScript 中可以通过数组、元祖去约束剩余参数的类型

js
function padding(t: number, ...rest: number[]) {} // 代表rest的参数为 Number类型

function padding(t: number, ...rest: [number, number, string]) {} // 使用Tupe的方式去约束

函数重载

同名函数,传入不同的参数,实现不同的功能,这就叫作函数重载。

  1. 函数重载不代表定义多个相同名称的函数是因为入参不同会调用不同的函数,其实际上还是调用最新的函数(原来的函数被覆盖)

  2. 用来对自定义支持不同入参的数量或者类型的函数类型的约束, 主要是约束如 ?: 可选参数

  3. 对函数表达式有效,对通过函数字面量定义的函数无效

js
// 定义TypeScirpt的约束(重载签名)
function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);

// 定义函数的实现签名
function padding(a: number, b?: number, c?: number, d?: any) {}

结果(只是在编译态有效,进行函数调用类型的检查)

js
// 定义函数的实现
function padding(a, b, c, d) {}

规则

  1. 有一个实现签名 + 一个或多个重载签名合成

如上述例子:存在一个函数的实现 和 三个重载签名

  1. 外部调用函数重载定义的函数时,只能调用重载签名,不能调用实现签名

  1. 调用重载签名的函数时,会根据传递的参数来判断你调用的是哪一个函数

重载签名是根据参数的类型和数量进行判断(不关心参数的参数名,下图:d 和 c 就是一样的),跟 JS 不同的时候是 TypeScript 是前面覆盖后面

  1. 只有一个函数体,只有实现签名配备了函数体,所有的重载签名都只有签名, 没有配备函数体