Background
Sometimes, We need to extend a native class(object) with inheritance. But some meta programmer has a different direction to solve it. They extend the native class by editing itself. It has beneficial because Not necessary to define a new extended class. There surely has some point you should take care of.
Let’s see on typescript
typescript provides these feature, it calls ‘Declaration merging‘
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
This is example, The Array object extedns by adding the uniq method which eliminating duplicated item in a Array.
array.extensions.ts
export {} declare global { interface Array<T> { uniq<T> (comparer: (value1: T, valu2: T) => boolean): T[]; contains<T> (value: T): boolean; } } /* eslint no-extend-native: ["error", { "exceptions": ["Array"] }] */ Array.prototype.uniq = function<T> (comparer: (value1: T, valu2: T) => boolean): T[] { return this.filter((value1, index1, array1): boolean => { const index2 = array1.findIndex((value2): boolean => comparer(value1, value2)) return (index1 === index2) }) }
To use this extension library, like this.
import './array.extensions' ['aaa','bbb','ccc','bbb','ccc'] .filter(elem => elem === 'ccc') .uniq((v1,v2) => (v1 === v2)) objectの配列でも [{ID:'aaa'}, {ID:'bbb'},{ID:'ccc'},{ID:'bbb'},{ID:'ccc'}] .filter(elem => elem.ID === 'ccc') .uniq((v1,v2) => (v1.ID === v2.ID))
Note
If you use eslint, You should turn off the no-extend-native rule. (like this)
/* eslint no-extend-native: ["error", { "exceptions": ["Array"] }] */
And, There is a risk of this feature that it spoil to native namespace. You should take care of spoiling namespace when you add (or extend) native object.