3.TypeScript函数完全指南:从基础到高级实战

小鱼
2025-08-15 19:58:33
TypeScript

函数是TypeScript应用程序的基石。掌握函数的使用技巧,能让你写出更健壮、更易维护的代码。本文将带你深入理解TypeScript函数的各种特性。

一、函数基础:两种定义方式

TypeScript支持JavaScript的两种函数定义方式:命名函数匿名函数

typescript

// 1. 命名函数
function greet(name: string): string {
  return `Hello, ${name}!`;
}

// 2. 匿名函数(函数表达式)
const greet2 = function(name: string): string {
  return `Hello, ${name}!`;
};

在实际开发中,选择哪种方式取决于使用场景:

  • 命名函数:适合主要功能、工具函数
  • 匿名函数:适合回调函数、一次性使用的函数

二、函数类型:确保输入输出安全

TypeScript的强大之处在于它能精确控制函数的输入和输出类型。

基本类型注解

typescript

// 参数类型和返回值类型
function add(x: number, y: number): number {
  return x + y;
}

完整函数类型

当需要将函数赋值给变量时,我们可以使用完整函数类型声明:

typescript

// 完整函数类型
const myAdd: (base: number, increment: number) => number = 
  function(x: number, y: number): number {
    return x + y;
  };

这种写法虽然略显冗长,但在复杂项目中能提高代码可读性。

三、灵活参数处理技巧

可选参数:处理非必填项

在实际业务中,我们经常遇到非必填参数的情况:

typescript

function buildFullName(firstName: string, lastName?: string): string {
  return lastName ? `${firstName} ${lastName}` : firstName;
}

console.log(buildFullName('张', '三')); // 张 三
console.log(buildFullName('李'));      // 李

重要规则

  • 可选参数必须位于必选参数之后
  • 可选参数不能出现在必选参数前面

默认参数:智能填充缺省值

当参数未传递时,使用默认值:

typescript

function createGreeting(name: string, greeting: string = 'Hello'): string {
  return `${greeting}, ${name}!`;
}

console.log(createGreeting('Alice'));       // Hello, Alice!
console.log(createGreeting('Bob', 'Hi'));   // Hi, Bob!

最佳实践

  • 默认参数可以放在任何位置,但建议放在参数列表末尾
  • 默认值可以是表达式,甚至是函数调用

剩余参数:处理可变参数列表

当参数数量不确定时,可以使用剩余参数语法:

typescript

function assembleCar(make: string, ...features: string[]): string {
  return `制造:${make},配置:${features.join('、')}`;
}

console.log(assembleCar('特斯拉', '自动驾驶', '全景天窗'));
// 制造:特斯拉,配置:自动驾驶、全景天窗

技术要点

  • 剩余参数必须是参数列表中的最后一个
  • 一个函数只能有一个剩余参数
  • 剩余参数会被当作数组处理

四、函数重载:处理复杂场景的利器

当函数需要处理多种参数类型时,函数重载提供了完美的解决方案。

实际案例:用户信息处理

假设我们需要一个函数,既能处理用户ID(number),也能处理用户名(string):

typescript

// 重载声明
function getUserInfo(id: number): string;
function getUserInfo(name: string): string;

// 函数实现
function getUserInfo(info: string | number): string {
  if (typeof info === 'number') {
    return `用户ID:${info}`;
  } else {
    return `用户名:${info}`;
  }
}

console.log(getUserInfo(1001));    // 用户ID:1001
console.log(getUserInfo('Alice')); // 用户名:Alice

复杂案例:API响应处理

处理不同状态码的API响应:

typescript

// 重载声明
function handleResponse(code: 200, data: string): void;
function handleResponse(code: 400, error: string): void;
function handleResponse(code: 500, error: string, details: string): void;

// 函数实现
function handleResponse(code: number, message: string, details?: string): void {
  switch(code) {
    case 200:
      console.log(`成功:${message}`);
      break;
    case 400:
      console.log(`客户端错误:${message}`);
      break;
    case 500:
      console.log(`服务器错误:${message},详情:${details}`);
      break;
  }
}

handleResponse(200, '操作成功');
handleResponse(400, '无效请求');
handleResponse(500, '内部错误', '数据库连接失败');

重载规则

  1. 重载声明必须紧挨着函数实现
  2. 重载声明中不能包含函数体
  3. 函数实现必须兼容所有重载声明

五、高级技巧:函数类型进阶

箭头函数的类型

typescript

const calculate: (x: number, y: number) => number = 
  (a, b) => a * b;

回调函数类型安全

typescript

function fetchData(callback: (data: string) => void): void {
  // 模拟异步操作
  setTimeout(() => callback('数据加载完成'), 1000);
}

fetchData(result => console.log(result));

函数类型作为参数

typescript

function processNumbers(
  numbers: number[],
  processor: (n: number) => number
): number[] {
  return numbers.map(processor);
}

const doubled = processNumbers([1, 2, 3], n => n * 2);
console.log(doubled); // [2, 4, 6]

六、最佳实践:编写高质量函数

  1. 单一职责原则:每个函数只做一件事
  2. 合理命名:函数名应准确描述其功能
  3. 控制参数数量:建议不超过3个参数
  4. 明确返回值:避免返回混合类型
  5. 使用重载代替复杂类型判断:提高可读性

七、实战应用场景

场景1:表单验证函数

typescript

// 重载声明
function validateInput(value: string, maxLength: number): boolean;
function validateInput(value: number, min: number, max: number): boolean;

// 函数实现
function validateInput(
  value: string | number, 
  minOrMax: number, 
  max?: number
): boolean {
  if (typeof value === 'string') {
    return value.length <= minOrMax;
  } else {
    return value >= minOrMax && value <= (max as number);
  }
}

console.log(validateInput('hello', 10));    // true
console.log(validateInput(15, 10, 20));     // true
console.log(validateInput(25, 10, 20));     // false

场景2:API请求函数

typescript

async function fetchAPI(
  endpoint: string,
  method: 'GET' | 'POST' = 'GET',
  body?: object
): Promise<any> {
  const options: RequestInit = {
    method,
    headers: { 'Content-Type': 'application/json' }
  };
  
  if (body) {
    options.body = JSON.stringify(body);
  }
  
  const response = await fetch(endpoint, options);
  return response.json();
}

// 使用示例
const userData = await fetchAPI('/api/users/1');
const updateResult = await fetchAPI('/api/users/1', 'POST', { name: '新名字' });
Copyright © 2025 aipanzhou.com All Rights Reserved.
备案号:黔ICP备2023000741号-1
贵公网安备 52022202000096号