函数类型:参数、返回值与重载

本节目标

函数类型标注涵盖:参数类型、返回值类型、可选 ?、默认参数。

// 运行环境:Node.js 16+ + typescript;类型检查 npx tsc --noEmit ts-l6.ts

// 完整标注:参数 + 返回值
function divide(a: number, b: number): number {
  return a / b
}

// 可选参数用 ?;默认参数自带「可选」语义且能推断类型
function greet(name: string, prefix = 'Hello'): string {
  return `${prefix}, ${name}`
}
greet('Tom')        // 'Hello, Tom'
greet('Tom', 'Hi')  // 'Hi, Tom'

// 把「函数」本身存进变量时,要写「函数类型」
type MathFn = (x: number, y: number) => number
const add: MathFn = (x, y) => x + y
console.log(add(1, 2)) // 3

函数重载:同一个函数根据参数不同返回不同类型。TS 用「多个声明 + 一个实现」表达:

// 重载签名(只声明,不实现)
function reverse(x: string): string
function reverse(x: number): number
// 实现签名(真正逻辑,参数要兼容上面所有声明)
function reverse(x: string | number): string | number {
  if (typeof x === 'string') return x.split('').reverse().join('')
  return Number(String(x).split('').reverse().join(''))
}
const r1 = reverse('abc')  // 推断为 string -> 'cba'
const r2 = reverse(123)    // 推断为 number -> 321

名词解释

函数类型(Function Type):函数在 TS 里也是一种「值」,所以它也有类型——长这样 (参数) => 返回值。当你把函数塞进变量、当参数传、当返回值返回时,就要用函数类型去描述它。它相当于「函数的身份证」,说明「这个函数长啥样、能吃啥、吐啥」。

函数重载(Overload):允许一个函数名根据「传入参数不同」表现出不同行为/返回不同类型。TS 的重载是「编译期的假象」——运行时只有一个实现,但编译期 TS 会按你写的多个签名分别检查调用是否合法。

课后练习

练习 1:写一个 createId 函数,传入 string 返回大写 ID,传入 number 返回字符串化 ID,用重载实现。

答案:

function createId(input: string): string
function createId(input: number): string
function createId(input: string | number): string {
  return String(input).toUpperCase()
}

练习 2:默认参数 function f(a = 1) 中 a 的类型被推断成什么?

答案:推断为 number,因为默认值 1 是 number;同时 a 自动成为可选参数,调用 f() 合法。

总结

我觉得函数类型是 TS 里「性价比最高」的知识点之一:一旦你习惯给「回调函数」「事件处理器」「高阶函数」标函数类型,编辑器提示会准得吓人,重构也敢下手。至于重载,我的态度是别滥用——它主要解决「同一个 API 因参数不同而语义不同」的场景(如 reverse)。如果你的函数只是「参数可选」,用 ? 或联合类型往往更直白;硬上重载反而让实现签名变得难读。记住:重载是给「调用方」看的友好界面,不是给「实现」增加难度的。