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

求实现支持可变长度元组的TypeScript数组divide函数类型定义

实现支持任意数量类型守卫的数组divide方法

需求是为数组扩展一个divide方法,接收任意数量的类型守卫/类类型守卫函数,将原数组按守卫顺序划分成对应数量的类型化数组组成的元组,不匹配任何守卫的元素直接丢弃。示例用法如下:

const [typeAs, typeBs, typeCs] = myArr.divide(isTypeA, isTypeB, isTypeC);
const [typeFs] = myArr.divide(isTypeF);
const [typeAs, typeFs, typeDs, typeCs, typeXYZs] = myArr.divide(isTypeA, isTypeF, isTypeD, isTypeC, isTypeXYZ);
// 支持任意数量守卫参数

之前已实现支持最多3个守卫的版本,但需要扩展为支持任意数量参数,核心难点在于编写能匹配任意长度元组的类型签名。


完整解决方案

1. 类型定义

通过TypeScript的泛型元组和映射类型,可以实现对任意数量守卫的类型推导:

// 定义类型守卫的通用类型,支持类型谓词或普通布尔返回函数
type TypeGuard<T> = ((input: unknown) => input is T) | ((input: unknown) => boolean);

// 映射守卫元组到对应的数组元组类型
type GuardToArray<T extends TypeGuard<any>[]> = {
  [K in keyof T]: T[K] extends TypeGuard<infer U> ? U[] : never;
};

// 扩展Array接口,添加divide方法的类型声明
declare global {
  interface Array<T> {
    divide<G extends TypeGuard<any>[]>(...guards: G): GuardToArray<G>;
  }
}

2. 方法实现

实现部分通过遍历数组元素,按守卫顺序依次匹配,将元素推入对应分组数组:

Array.prototype.divide = function <G extends TypeGuard<any>[]>(...guards: G) {
  // 初始化对应数量的空数组组成的元组
  const result = guards.map(() => []) as GuardToArray<G>;

  this.forEach(item => {
    // 遍历守卫,找到第一个匹配的分组
    for (let i = 0; i < guards.length; i++) {
      if (guards[i](item)) {
        result[i].push(item);
        break; // 匹配到第一个守卫后停止检查
      }
    }
    // 不匹配任何守卫的元素直接丢弃
  });

  return result;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:10:39