Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active November 26, 2020 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/ab97f2a2bd23defc2a12e0de9e801530 to your computer and use it in GitHub Desktop.
Save tompng/ab97f2a2bd23defc2a12e0de9e801530 to your computer and use it in GitHub Desktop.
type MapProxyValue<T> = T extends (...args: infer U) => infer V
? (...args: U) => V[]
: T[]
type MapProxy<T> = {
[key in Exclude<keyof T, '_avoid_ts_something'>]: MapProxyValue<T[key]>
}
class Array2<T> extends Array<T> {
map2<U>(f: (v: T) => U): U[]
map2(): MapProxy<T>
map2(f?: (v: T) => any) {
if (f) return this.map(f)
return new Proxy(this, {
get(arr: T[], prop: string) {
if (arr.every(v => typeof v[prop] === 'function')) {
return (...args: any[]) => arr.map(v => v[prop](...args))
} else {
return arr.map(v => v[prop])
}
}
}) as any
}
}
console.log(new Array2('a', 'bc', 'def').map2(a => a.length))
console.log(new Array2('a', 'bc', 'def').map2().length)
console.log(new Array2('a', 'bc', 'def').map2().substr(1))
console.log(new Array2('a', 'bc', 'def').map2().substr(1,1))
const originalMap = Array.prototype.map
Array.prototype.map = function(f) {
if (f) return originalMap.call(this, f)
return new Proxy(this, {
get(arr, prop) {
if (arr.every(v => typeof v[prop] === 'function')) {
return (...args) => originalMap.call(arr, v => v[prop](...args))
} else {
return originalMap.call(arr, v => v[prop])
}
}
})
}
;['a', 'bc', 'def'].map().length // => [1, 2, 3]
;['a', 'bc', 'def'].map().substr(1,2) // => ["", "c", "ef"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment