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

如何为自定义数组遍历函数正确添加TypeScript类型?

优化自定义find函数的TypeScript类型

问题背景

我编写了一个遍历数组的自定义find函数,实现如下:

function find(array, callback, context) {
    const { length } = array;
    let index = 0;

    while (index < length) {
        if (callback.call(context, array[index], index, array)) {
            return index;
        }
        index += 1;
    }

    return -1;
}

目前我给它添加的TypeScript类型如下:

function find(
    array: ArrayLike<any>,
    callback: (this: typeof context, item: any, index: number, array: ArrayLike<any>) => boolean,
    context?: any
) {
    // ...
}

现在想优化参数类型描述,实现两个目标:

  • 回调中的item参数类型与数组元素类型完全一致
  • 函数参数里的array和回调里的array引用指向同一对象(类型层面约束一致性)

优化方案

使用泛型可以完美解决这两个问题,通过泛型关联数组类型、元素类型以及上下文类型,具体实现如下:

function find<T extends ArrayLike<any>, C>(
    array: T,
    callback: (this: C, item: T[number], index: number, array: T) => boolean,
    context?: C
) {
    const { length } = array;
    let index = 0;

    while (index < length) {
        if (callback.call(context, array[index], index, array)) {
            return index;
        }
        index += 1;
    }

    return -1;
}

方案说明

  1. 泛型T的作用:

    • 约束为ArrayLike<any>,兼容数组和类数组对象(比如NodeList、arguments等)
    • T[number]会自动推导数组/类数组的元素类型,确保回调里的item类型和传入的array元素类型完全匹配
    • 回调中的array参数指定为T,确保它和函数第一个参数array的类型完全一致,从类型层面保证二者是同一对象类型
  2. 泛型C的作用:

    • 专门用来表示上下文context的类型,替代原来的typeof context,让回调中this的类型更明确、更严谨

使用示例

普通数组场景

const numArr = [1, 2, 3, 4];
const index = find(numArr, function(item, idx, array) {
    // item 类型自动推导为 number
    // array 类型自动推导为 number[],和传入的numArr完全一致
    return item > 2;
});

类数组场景

const divList = document.querySelectorAll('div');
const divIndex = find(divList, function(item, idx, array) {
    // item 类型自动推导为 Element
    // array 类型自动推导为 NodeListOf<Element>
    return item.classList.contains('target');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:17:11