如何为自定义数组遍历函数正确添加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; }
方案说明
泛型
T的作用:- 约束为
ArrayLike<any>,兼容数组和类数组对象(比如NodeList、arguments等) T[number]会自动推导数组/类数组的元素类型,确保回调里的item类型和传入的array元素类型完全匹配- 回调中的
array参数指定为T,确保它和函数第一个参数array的类型完全一致,从类型层面保证二者是同一对象类型
- 约束为
泛型
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
相关产品推荐
相关产品推荐

