如何使⽤Ts泛型写⼀个通⽤的遍历数组和对象的⽅法
使⽤Ts编写⼀个遍历数组和对象的⽅法
type Obj<T=any>={[key in string|number]:T}
type Keys<T>=T extends(infer U)[]?U:T[Extract<keyof T,string>]
type Callback<T extends Obj>=(item:T extends(infer U)[]?U:T[Extract<keyof T,string>], index:number, source?:T)=>any
type AsyncCallback<T extends Obj>=(item:T extends(infer U)[]?U:T[Extract<keyof T,string>], index:number, source?:T)=>Promise<any> const isArray =(type:unknown):type is Array<any>=>type instanceof Array
const isObject =(type:unknown):type is Obj =>typeof type==='object'
/**
* 同步遍历当前元素
* @param source 需要遍历的元素
* @param fn 遍历的同步回调返回 true 可以停⽌遍历
*/
export const each =<T extends Obj>(source:T, fn: Callback<T>):void=>{
typeof array
if(isArray(source)){
for(let i =0, length = source.length; i < length; i++){
if(fn(source[i], i, source)===true)return
}
}else if(isObject(source)){
const keys = Reflect.ownKeys(source)as Array<keyof T>
for(let i =0, length = keys.length; i < length; i++){
const key = keys[i]
if(Reflect.has(source, key)&& key !=='constructor'){
if(fn(source[key], i, source)===true)return
}
}
}else{
fn(source,-1)
}
}
/**
* 倒序遍历
* @param source 需要遍历的元素
* @param fn 遍历的同步回调返回 true 可以停⽌遍历
*/
export const reverseEach =<T extends Obj>(source:T, fn: Callback<T>):void=>{
if(isArray(source)){
for(let i = source.length -1; i >=0; i--){
if(fn(source[i], i, source)===true)return
}
}else if(isObject(source)){
const keys = Reflect.ownKeys(source)as Array<keyof T>
for(let i = keys.length -1; i >=0; i--){
const key = keys[i]
if(Reflect.has(source, key)&& key !=='constructor'){
if(fn(source[key], i, source)===true)return
}
}
}else{
fn(source,-1)
}
}
/**
* 异步遍历当前元素
* @param source 需要遍历的元素
* @param fn 遍历的异步回调返回 true 可以停⽌遍历
*/
*/
export const asyncEach =async<T extends Obj>(source:T, fn: AsyncCallback<T>):Promise<void>=>{ if(isArray(source)){
for(let i =0; i < source.length; i++){
const result =await fn(source[i], i, source)
if(result ===true)return
}
}else if(isObject(source)){
const keys = Reflect.ownKeys(source)as Array<keyof T>
for(let i =0, length = keys.length; i < length; i++){
const key = keys[i]
if(Reflect.has(source, key)&& key !=='constructor'){
const result =await fn(source[key], i, source)
if(result ===true)return
}
}
}else{
await fn(source,-1)
}
}
使⽤
const list =[1,2,3]
each(list,(item, index)=>{
if(item ===2){
console.log(index)
return true
}
console.log('111')
})
const obj:{ a:number, b:string, c:{ d:number}}={ a:12, b:'123', c:{ d:1234}}
each(obj,(item, index)=>{
if(typeof item ==='object'){
console.log(index, item.d)
return true
}
console.log('222')
})

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。