I need the ability to easily sort collections and I've chosen to extend the Array primitive. I realize this is considered bad practice in most cases, but this will be used only internally (not a shared lib). No matter what approach I've tried I'm not getting a working result. I keep getting the error: TypeError: Attempted to assign to readonly property
. This is a simplified example of my latest iteration. I have a more complete version of this working in the playground so I'm assuming he problem lies with the angular-cli config/build process???
interface Array<T> {
$sortBy(sortKey:string): T[];
}
if (!Array.prototype['$sortBy']) {
Object.defineProperty(Array.prototype, '$sortBy', {
value: function(sortKey) {
return this.sort( function(a, b) { // TypeError here???
if (a[sortKey] < b[sortKey]) { return -1; }
if (a[sortKey] > b[sortKey]) { return 1; }
return 0;
});
}
}
}
I've also tried this approach but my IDE (VSCode) gives me the error: [ts] Property '$sortBy' does not exist on type 'any[]'.
Intellisense error here
|
V
Array.prototype.$sortBy = function(sortKey:string){
return this.sort( function(a, b) {
...
});
}
tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"lib": [
"es2016"
]
}
}
tsconfig.app.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"lib": [
"es2016",
"dom"
],
"outDir": "../out-tsc/app",
"target": "es5",
"module": "es2015",
"baseUrl": "",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
I had this problem as well, so just pasting my results here in case someone needs.
in your main.ts
file add this:
// Here will be all extension methods that will be shared globally across the app
declare global {
interface Array<T> {
sortAlphaNumeric(fieldName: string): Array<T>;
}
}
then you can create a file with this:
/**
* The extension of Array type allows to sort AlphaNumeric data
* @param fieldName {string} requires the field name which you want to sort by
*/
Array.prototype.sortAlphaNumeric = function (fieldName: string) {
return this.sort((a, b) => {
return a[fieldName].toLowerCase().localeCompare(b[fieldName].toLowerCase(), undefined, {
numeric: true,
sensitivity: 'base'
});
});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With