TypeScript 函数完全指南:类型声明、参数处理与重载详解
本文深入解析 TypeScript 中函数的使用,涵盖函数声明的三种方式、类型注解与推导机制。详细讲解可选参数、默认参数及剩余参数的类型定义,探讨 void 与 undefined 返回值区别。重点介绍 this 类型的声明方法及 strict 模式下的处理,并演示如何通过重载签名实现多态行为,帮助开发者掌握 TS 函数的核心特性。
前言
尽管 JavaScript 和 TypeScript 均支持面向对象编程,但在实际开发中,函数依然是最核心的代码组织单元。在 TypeScript 中,函数被视为一等公民。本文将系统介绍 TypeScript 中函数的使用规范,主要涵盖以下核心内容:
- 函数类型声明
- 函数参数类型:可选参数、默认参数、剩余参数
- 函数返回值类型
- this 类型
- 函数重载
函数类型
在面试中,JavaScript 的数据类型是一个高频考点,其中往往包含函数类型。
在原生 JavaScript 中,函数类型的概念较为模糊,严格来说它只有类型的概念而缺乏严格的类型实质。得益于 TypeScript 强类型系统的加持,我们现在可以精确地定义函数的类型结构。
声明函数类型存在多种途径,例如通过 interface 接口定义函数类型、利用 type 关键字声明函数类型别名,或在类声明中定义方法类型等。
无论采用何种方式,核心原则始终一致:只需关注函数参数的类型定义以及返回值的类型。
接下来,我们将从函数的具体声明方式入手,深入探讨函数类型的应用场景。
函数的声明方式
在 TypeScript 中,存在三种最基础的函数声明模式。
使用 function 关键字进行标准函数声明:
function add(a: number, b: number): number {
return a + b
}
通过函数表达式(Function Expression)进行声明:
let add = function (a: number, b: number): number {
return a + b
}
或者使用箭头函数(Arrow Function)进行声明:
let add = (a: number, b: number): number => {
return a + b
}
上述三种函数声明方式与 JavaScript 中的写法基本一致,主要区别在于增加了两个 TypeScript 特有的要求:
- 函数参数需要明确指定类型
- 函数返回值也需要明确指定类型
那么,函数的具体类型定义在哪里体现呢?只需将鼠标悬停在函数名称上,即可在 IDE 中查看到其类型信息:



这与声明普通变量时的类型推断逻辑完全一致:
let name = 'kunwu'
如果在声明函数时未手动添加类型注解,TypeScript 编译器会自动根据函数体推导出具体的类型。上述截图中红框标识出的内容,即为编译器自动推导出的结果。
函数的类型注解
函数的类型结构通常表现为 (参数:类型) => 返回值类型,因此函数的类型注解写法如下:
let add: (a: number, b: number) => number = function (a, b) {
return a + b
}
通常情况下,函数的类型定义可能较为冗长。此时,可以利用 type 关键字定义类型别名,创建一个标识符来代表该复杂类型:
type Add = (a: number, b: number) => number
let add: Add => number = function (a, b) {
return a + b
}
通过这种方式,无论是声明函数类型还是使用函数类型,代码结构都显得更加简洁直观。
对象中的函数类型
函数的参数
在声明函数时,可以使用类型注解来指定参数的具体类型。若未指定类型,TypeScript 默认将其类型推断为 any。
function add (a: number, b: number) :number {
return a + b
}

可选参数
可选参数使用 ? 符号进行标记,且必须放置在所有固定参数的后方:
const fn = (a: number, b?:number) => {
if(b) {
return a + b
} else {
return a
}
}
可选参数意味着该参数在调用时可有可无。通过观察编译器的类型推导结果,可能会产生一种错觉,即可选参数等同于一个联合类型:

但实际上,这两者并不等同。
可选参数表示该参数在调用时是可选的,但如果传入了值,则必须严格符合指定的类型。
而直接将参数类型声明为 string|undefined,意味着这是一个必传参数,调用者必须提供具体的实参值。
参数默认值
对于参数的默认值,可以在参数类型之后使用 = 符号进行声明:
const fn = (a: number, b: number = 10): number => {
return a + b
}
剩余参数
剩余参数是 ES6 引入的特性,使用剩余运算符 ... 可以获取函数实参中未被形参声明的剩余变量,其结果是一个数组,例如:
function add(a,b, ...args) {
console.log(args)
}
add(1,2,3,4,5)
在上述示例中,剩余参数 args 的值即为 [3, 4, 5]。
在 TypeScript 中,剩余参数同样需要进行类型声明,通常将其声明为数组类型或元组类型。
function add(a: number, b: number, ...args: number[]) {
console.log(c)
}
剩余参数与其他固定参数存在显著差异。固定参数一旦声明了类型,调用时必须传入该类型的值;而剩余参数虽然也声明了类型,但其调用是可选的,可以传入零个、一个或多个参数,例如:
function add(a: number, b: number, ...args: number[]) {
console.log(args)
}
add(1, 2) // [ ]
add(1, 2, 3) // [ 3 ]
add(1, 2, 3, 4) // [ 3, 4 ]
此外,还可以将剩余参数的类型声明为元组类型。在元组中,依然可以使用可选参数,通过在参数后添加 ? 符号来表示:
function log( ...args: [string, number, boolean?]) {
console.log(args)
}
log('Shinichi', 17) // [ 'Shinichi', 17 ]
log('Zoro', 19, true) // [ 'Zoro', 19, true ]
函数的返回值类型
函数的返回值类型可以通过类型注解显式指定。若未指定,TypeScript 编译器会根据函数体内的 return 语句自动推断返回值类型,因此我们也可以省略返回值类型的声明。
在 TypeScript 的基本类型中,void 类型表示空类型,其唯一用途是作为函数的返回值类型。当一个函数内部没有 return 语句时:

如果函数使用 return 语句显式返回了 undefined 值,则其返回值类型将被推断为 undefined,而非 void:

但是,此时可以通过类型注解强制将返回值类型指定为 void:

this 类型
在 JavaScript 函数中,this 关键字随处可见。关于 this 指向的问题也是前端开发中的基础知识点。
默认情况下,TypeScript 编译器会将函数中的 this 类型设置为 any,这意味着编译器不会对 this 进行类型检查,允许任意使用 this 对象,例如:
function fn() {
this.name = 'Naruto'
this.age = 18
}
同时,TypeScript 编译器提供了一个编译选项 --noImplicitThis。开启该选项后,编译器将检查 this 的类型,此时必须明确指定其类型,否则会报错,如下所示:

那么,如何为 this 声明具体的类型呢?
声明 this 类型
TypeScript 函数中存在一个特殊的 this 参数,用于指定函数内部使用的 this 对象的类型。该参数必须定义在形参列表的第一个位置。
沿用上述示例,若需为函数中的 this 指定具体类型,写法如下:
function fn(this: {name: string, age: number}) {
this.name = 'Naruto'
this.xxx = 'xxx'
}
直接在函数参数列表中声明 this 类型可能显得不够优雅,可以使用 type 关键字定义类型别名,然后在函数签名中引用:
type Person = {name: string, age: number}
function fn(this: Person) {
this.name = 'Naruto'
this.age = 18
}
当定义了 this 类型后,函数的调用方式也会发生变化,必须使用 call 或 apply 方法:
type Person = {name: string, age: number}
function fn(this: Person, a: number) {
this.name = 'Naruto'
this.age = 18
}
fn.call({name: 'Naruto', age: 18}, 10)
fn.apply({name: 'Naruto', age: 18}, [10])
若像以前那样直接调用函数,将会导致错误:
fn(10) // X
函数重载
面向对象编程具有三大特征:封装、继承和多态。多态的一种典型表现即为函数重载。
函数重载允许多次声明同名函数,但它们的参数类型或参数个数不同。在调用时,系统会根据传入参数的类型和数量,确定执行具体的函数逻辑。
函数重载是后端语言(如 Java)中的常见概念,例如在 Java 中:
// 两个整数的和
public static int add(int a, int b) {
return a+b;
}
// 三个整数的和
public static int add(int a, int b, int c) {
return add(a,b)+c;
}
JavaScript 本身并不支持函数重载。如果多次声明同名函数,后声明的函数会覆盖先声明的函数。但是,JavaScript 可以利用 arguments 对象,结合对实参类型的判断来模拟重载功能,例如:
function add() {
let args = Array.from(arguments)
if(args.length == 2) {
return args[0] + args[1]
} else if(args.length == 3) {
return args[0] + args[1] + args[3]
}
}
add(1,2)
add(1, 2, 3)
在 TypeScript 中,直接多次声明同名函数会导致编译器报错。但 TypeScript 提供了实现函数重载的标准方法:先通过 function 关键字声明多个重载签名,最后编写一个具体的函数实现。
function add(a: number, b: number) : number
function add(a: string, b: string) : string
function add(a: number|string, b: number | string) {
if(typeof a === 'number' && typeof b === 'number') {
return a + b
} else if(typeof a === 'string' && typeof b === 'string') {
return a + b
}
}
add(1, 2)
add('10', '20')
由于在声明重载签名时已经确定了函数的返回值类型,在编写函数实现时,无需再指定返回值类型。编译器会根据重载签名自动推导返回值类型。
需要注意的是,TypeScript 的函数重载本质上是一种伪重载,最终仍需依靠类型判断来执行不同的逻辑分支。
此外,还需注意一点:声明函数重载签名和函数实现必须写在同一代码块中,中间不能插入其他语句。
总结
本文详细介绍了 TypeScript 中关于函数的相关知识,包括函数的多种声明方式、函数类型的声明方法、函数参数与返回值的类型处理、函数重载机制以及 this 类型的定义。大部分内容与 JavaScript 相似,主要需要额外关注的是 this 类型的声明和函数重载的实现细节。
以上就是如何在TypeScript中使用函数的详细内容,更多关于TypeScript 函数使用的资料请关注本站其它相关文章!
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36








