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

TypeScript中是否有更优的管道化Type Guard函数实现方案?

实现方案

通过 TypeScript 递归可变元组约束即可实现任意长度的类型守卫管道,无需手动声明大量泛型参数,天然支持前一个守卫的输出类型自动作为下一个守卫的入参类型。

完整实现代码如下:

// 基础类型守卫定义
type AnyTypeGuard = (value: any, ...args: any[]) => value is any;

// 递归约束守卫链的类型,确保上一个守卫的输出是下一个守卫的输入
type GuardChain<PrevType, GuardList extends AnyTypeGuard[]> = 
  GuardList extends [infer FirstGuard, ...infer RestGuards]
    ? FirstGuard extends (value: PrevType, ...args: any[]) => value is infer NextType
      ? RestGuards extends AnyTypeGuard[]
        ? [FirstGuard, ...GuardChain<NextType, RestGuards>]
        : never
      : never
    : [];

// 递归合并所有守卫的断言类型,得到最终的交叉类型
type CombinedGuardType<GuardList extends AnyTypeGuard[], Result = unknown> =
  GuardList extends [infer FirstGuard, ...infer RestGuards]
    ? FirstGuard extends (value: any, ...args: any[]) => value is infer U
      ? RestGuards extends AnyTypeGuard[]
        ? CombinedGuardType<RestGuards, Result & U>
        : never
      : never
    : Result;

// 管道函数实现
function guardPipe<T extends AnyTypeGuard[]>(
  ...guards: GuardChain<unknown, T>
): (value: unknown) => value is CombinedGuardType<T> {
  return (value: unknown): value is CombinedGuardType<T> => {
    for (const guard of guards) {
      if (!guard(value)) return false;
    }
    return true;
  };
}

使用示例

const isFoobar = guardPipe(
  (val): val is string => typeof val === 'string',
  (val): val is `foo${string}` => val.startsWith('foo'), // val 自动推导为 string
  (val): val is 'foobar' => val === 'foobar' // val 自动推导为 `foo${string}`
);

const test = {} as unknown;
if (isFoobar(test)) {
  test // 自动推导为字面量类型 'foobar'
}

// 错误用法会被 TypeScript 自动拦截
// const wrongGuard = guardPipe(
//   (val): val is number => typeof val === 'number',
//   (val: string) => val.startsWith('a') // 类型不匹配直接报错
// )

核心逻辑说明

  • GuardChain 从第一个守卫入参为 unknown 开始递归遍历守卫列表,强制要求每个守卫的入参类型等于上一个守卫的断言输出类型,从类型定义层面保证守卫链的合法性。
  • CombinedGuardType 递归收集所有守卫的断言类型做交叉,最终返回的守卫函数会给出最精确的收敛类型。
  • 运行时逻辑非常简单,遍历所有守卫依次校验,全部通过才返回 true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:54:04