源本科技 | 码上会

TypeScript 函数兼容性

2026/04/14
5
0

引言

函数兼容性是指在函数赋值、回调传递、类型匹配等场景中,判断源函数能否被赋值给目标函数类型。TypeScript 函数兼容遵循结构化类型规则,核心校验维度包含:参数个数、参数类型、返回值类型,同时支持可选参数、剩余参数、函数重载的兼容判断。

参数个数兼容性

函数参数个数是兼容性的基础规则: 源函数的参数个数 必须小于等于 目标函数的参数个数 简单理解:参数更少的函数,可以兼容参数更多的函数类型。

// 目标函数:2 个参数
type TargetFunc = (a: number, b: number) => void;
// 源函数:1 个参数
type SourceFunc = (a: number) => void;

const source: SourceFunc = (x) => console.log(x);
// 兼容:源函数参数更少,满足目标函数要求
const target: TargetFunc = source;

适用场景:数组的 forEach 回调,只传一个参数也能兼容完整的回调类型。

参数类型兼容性

源函数的每一个对应位置参数,类型必须能赋值给目标函数的参数类型,遵循类型兼容规则

type A = (x: number) => void;
type B = (x: string) => void;

let a: A = (x) => {};
let b: B = a; // 报错:number 与 string 类型不兼容

只有对应位置的参数类型兼容,函数才能完成赋值;参数类型不匹配,直接判定为不兼容。

可选和剩余参数

可选参数、剩余参数是参数个数的特殊形式,兼容性规则:

  1. 可选参数与必选参数可以互相兼容

  2. 剩余参数等价于无限个可选参数

  3. 核心依旧遵循:源参数个数 ≤ 目标参数个数

// 源函数:1 个必选 + 1 个可选参数
type Source = (x: number, y?: string) => void;
// 目标函数:1 个必选 + 剩余参数(无限个字符串)
type Target = (x: number, ...rest: string[]) => void;

const source: Source = (x, y) => {};
// 兼容:剩余参数兼容所有可选/必选参数
const target: Target = source;

剩余参数的灵活性最高,可以兼容任意个数的可选 / 必选参数,是函数兼容的常用场景。

返回值类型兼容性

函数返回值遵循协变规则源函数的返回值类型,必须能赋值给目标函数的返回值类型 源返回值结构 ≥ 目标返回值结构,即为兼容。

// 基础类型不兼容
type A = () => number;
type B = () => string;
let a: A = () => 42;
let b: B = a; // 报错:number 无法赋值给 string

// 对象类型兼容(结构满足即可)
type Obj1 = { name: string };
type Obj2 = { name: string; age: number };
type Fn1 = () => Obj1;
type Fn2 = () => Obj2;

const fn2: Fn2 = () => ({ name: "刃", age: 18 });
const fn1: Fn1 = fn2; // 兼容:源返回值满足目标结构

函数重载兼容性

带有重载的函数,赋值时目标函数必须兼容源函数的所有重载签名。 TypeScript 会校验每一个重载声明,确保完全匹配。

// 函数重载
function foo(x: number): void;
function foo(x: string): void;
function foo(x: any): void {
  console.log(typeof x === 'number' ? 'Number' : 'String');
}

// 兼容:any 类型可以匹配所有重载参数
let bar: typeof foo = (x: any) => {};

// 不兼容:无法匹配 number 类型的重载
// let err: (x: string) => void = foo;

重载函数赋值时,必须满足所有重载签名的参数、返回值兼容要求。


总结

  1. 核心规则:函数兼容看三点 → 参数个数(源 ≤ 目标)、参数类型(对应兼容)、返回值(源 ≥ 目标)

  2. 特殊参数:可选参数、剩余参数灵活兼容,剩余参数优先级最高;

  3. 重载函数:必须满足所有重载签名的兼容性,是最严格的函数匹配场景。