函数类型

TypeScript 为函数提供了强大的类型支持,包括参数类型、返回值类型、重载等特性。


函数类型定义

基本语法

// 函数声明
function add(a: number, b: number): number {
  return a + b;
}
 
// 函数表达式
const subtract = function(a: number, b: number): number {
  return a - b;
};
 
// 箭头函数
const multiply = (a: number, b: number): number => a * b;

完整函数类型

// 完整的类型注解
const divide: (a: number, b: number) => number = (a, b) => a / b;
 
// 使用类型别名
type MathOperation = (a: number, b: number) => number;
const modulo: MathOperation = (a, b) => a % b;
 
// 使用接口
interface Calculator {
  (a: number, b: number): number;
}
const power: Calculator = (a, b) => Math.pow(a, b);

参数类型

可选参数

function greet(name: string, greeting?: string): string {
  return `${greeting || "Hello"}, ${name}!`;
}
 
greet("Alice");           // "Hello, Alice!"
greet("Bob", "Hi");       // "Hi, Bob!"

默认参数

function createUser(name: string, age: number = 18): { name: string; age: number } {
  return { name, age };
}
 
createUser("Alice");      // { name: "Alice", age: 18 }
createUser("Bob", 25);    // { name: "Bob", age: 25 }

剩余参数

function sum(...numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}
 
sum(1, 2, 3);       // 6
sum(1, 2, 3, 4, 5); // 15
 
// 带固定参数
function log(prefix: string, ...messages: string[]): void {
  console.log(prefix, ...messages);
}

解构参数

interface Options {
  url: string;
  method?: string;
  timeout?: number;
}
 
function request({ url, method = "GET", timeout = 5000 }: Options): void {
  console.log(`${method} ${url} (timeout: ${timeout})`);
}
 
request({ url: "https://api.example.com" });

返回值类型

显式返回类型

function getString(): string {
  return "hello";
}
 
function getNumber(): number {
  return 42;
}
 
function getBoolean(): boolean {
  return true;
}

void 返回类型

function log(message: string): void {
  console.log(message);
  // 没有返回值,或返回 undefined
}
 
// 注意:回调函数的 void 返回类型允许返回值
const callbacks: (() => void)[] = [];
callbacks.push(() => 123); // 合法,但返回值被忽略

never 返回类型

// 抛出异常
function throwError(message: string): never {
  throw new Error(message);
}
 
// 无限循环
function infiniteLoop(): never {
  while (true) {}
}

类型推断

// TypeScript 会自动推断返回类型
function add(a: number, b: number) {
  return a + b; // 推断为 number
}
 
// 复杂情况建议显式声明
function getData(id: number): Promise<{ name: string }> {
  return fetch(`/api/users/${id}`).then(res => res.json());
}

函数重载

当函数根据不同参数返回不同类型时使用:

// 重载签名
function reverse(value: string): string;
function reverse(value: number[]): number[];
 
// 实现签名
function reverse(value: string | number[]): string | number[] {
  if (typeof value === "string") {
    return value.split("").reverse().join("");
  }
  return value.slice().reverse();
}
 
// 使用
const str = reverse("hello");    // string
const arr = reverse([1, 2, 3]);  // number[]

复杂重载示例

interface User {
  id: number;
  name: string;
}
 
// 根据参数数量返回不同类型
function getUser(id: number): User;
function getUser(name: string): User[];
function getUser(idOrName: number | string): User | User[] {
  if (typeof idOrName === "number") {
    return { id: idOrName, name: "User" };
  }
  return [{ id: 1, name: idOrName }];
}
 
const user = getUser(1);       // User
const users = getUser("John"); // User[]

this 类型

显式 this 参数

interface Button {
  label: string;
  onClick(this: Button): void;
}
 
const button: Button = {
  label: "Submit",
  onClick() {
    console.log(this.label); // this 被正确推断为 Button
  }
};

this 类型用于链式调用

class Calculator {
  private value: number = 0;
 
  add(n: number): this {
    this.value += n;
    return this;
  }
 
  subtract(n: number): this {
    this.value -= n;
    return this;
  }
 
  getResult(): number {
    return this.value;
  }
}
 
const result = new Calculator()
  .add(10)
  .subtract(3)
  .add(5)
  .getResult(); // 12

泛型函数

基本泛型函数

function identity<T>(value: T): T {
  return value;
}
 
// 显式指定类型
identity<string>("hello");  // string
identity<number>(42);       // number
 
// 类型推断
identity("hello");  // 推断为 string
identity(42);       // 推断为 number

多个类型参数

function pair<K, V>(key: K, value: V): [K, V] {
  return [key, value];
}
 
const p = pair("name", "Alice"); // [string, string]
const q = pair(1, true);         // [number, boolean]

泛型约束

interface Lengthwise {
  length: number;
}
 
function logLength<T extends Lengthwise>(value: T): T {
  console.log(value.length);
  return value;
}
 
logLength("hello");      // 5
logLength([1, 2, 3]);    // 3
// logLength(123);       // 错误:number 没有 length 属性

回调函数类型

// 同步回调
function process(callback: (data: string) => void): void {
  callback("processed data");
}
 
// 异步回调
function fetchData(callback: (error: Error | null, data?: string) => void): void {
  // ...
}
 
// 使用泛型
function map<T, U>(arr: T[], fn: (item: T, index: number) => U): U[] {
  return arr.map(fn);
}
 
const numbers = [1, 2, 3];
const strings = map(numbers, n => n.toString()); // string[]

函数类型工具

Parameters 提取参数类型

function greet(name: string, age: number): string {
  return `${name} is ${age}`;
}
 
type GreetParams = Parameters<typeof greet>; // [string, number]

ReturnType 提取返回类型

function createUser() {
  return { id: 1, name: "Alice" };
}
 
type User = ReturnType<typeof createUser>; // { id: number; name: string }

构造函数类型

interface UserConstructor {
  new (name: string, age: number): User;
}
 
class User {
  constructor(public name: string, public age: number) {}
}
 
function createInstance(ctor: UserConstructor, name: string, age: number): User {
  return new ctor(name, age);
}

最佳实践

  1. 优先使用箭头函数:避免 this 绑定问题
  2. 显式声明返回类型:提高代码可读性和类型安全
  3. 避免过多参数:超过 3 个参数考虑使用对象
  4. 合理使用重载:优先使用联合类型,复杂场景才用重载
  5. 泛型命名规范T 类型、K 键、V 值、E 元素
// 推荐:使用对象参数
interface RequestOptions {
  url: string;
  method: string;
  headers?: Record<string, string>;
  body?: unknown;
}
 
function request(options: RequestOptions): Promise<Response> {
  // ...
}
 
// 不推荐:过多位置参数
function request(
  url: string,
  method: string,
  headers?: Record<string, string>,
  body?: unknown
): Promise<Response> {
  // ...
}

typescript 函数 类型