You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中预填充首参的partial函数如何正确标注类型

问题描述

假设我有一个partial()函数,该函数接收一个可调用对象以及需要传入它的若干参数,功能是预填充该可调用对象的第一个参数。请问应当如何为该函数的参数添加类型标注,才能保证无论传入什么可调用对象,类型检查都可以正常工作?

初始无类型代码

function foo(a: string, b: number, c: string) {
  console.log('foo', a, b, c)
}

function bar(a: string) {
  console.log('bar', a)
}

function partial(callable, ...args) {
  callable('identity', ...args)
}

无效的尝试方案

以下是我之前尝试的实现,但无法正常通过类型校验:

partial<T>(callable: (...args: [string, ...T[]]) => void, ...args: T[]) {
  callable('partial a', ...args);
}

这个写法的核心问题是将剩余参数的类型统一推断为T[]数组类型,丢失了每个参数位置的独立类型信息,也无法校验参数数量是否匹配,比如传入foo时,要求第二个参数是number、第三个是string,这个写法无法约束传入的剩余参数和原函数参数一一对应。

正确类型标注实现

核心思路是用泛型捕获传入函数的完整类型,通过infer关键字推导原函数第一个固定为string的参数之后的剩余参数元组类型,将其作为partial函数接收的剩余参数类型,即可实现完整的类型校验:

// 独立函数版本
function partial<F extends (first: string, ...rest: any[]) => any>(
  callable: F,
  ...args: F extends (first: string, ...rest: infer R) => any ? R : never
) {
  callable('identity', ...args);
}

// 类方法版本(和类内定义格式对齐)
class YourClass {
  partial<F extends (first: string, ...rest: any[]) => void>(
    callable: F,
    ...args: F extends (first: string, ...rest: infer R) => void ? R : never
  ) {
    callable('partial a', ...args);
  }
}

类型校验效果

  • 调用partial(bar)时无需传入额外参数,类型检查正常通过
  • 调用partial(foo, 123, 'test')时,传入的剩余参数和foo第一个参数之后的b: number, c: string类型完全匹配,类型检查通过
  • 如果调用partial(foo, 'wrong', 'test'),第二个参数传入字符串而非要求的数字类型,TS会直接抛出类型错误
  • 如果调用partial(foo, 123)缺少第三个要求的字符串类型参数,TS也会报参数数量不匹配的错误
  • 如果传入的可调用对象第一个参数不是string类型,TS同样会抛出类型错误,符合预填充值为字符串的场景要求

内容的提问来源于stack exchange,提问作者Leonardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:54:38