I need to have some global prototype functions on the string class. Eg.
string.prototype.trimWhiteSpaces = function () {
return this.replace(/ +/g, '');
}
I am using Angular CLI and I want this function to be accessible to all strings across my Angular 4 app. I have added the code snippet to a file called prototypes.js
and in the .angular-cli.json
I loaded the file
"scripts": [
"assets/js/prototypes.js",
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js",
"../node_modules/moment/min/moment.min.js"
],
However, I keep getting the following error when I compile my project
Property 'trimWhiteSpaces' does not exist on type 'string'.
How do I make such functions accessible throughout my application
The problem is TypeScript doesnt know about these type definitions.
Provide definitions for each of the methods you're using
Open typings.d.ts and add the following:
interface String {
trimWhiteSpaces: () => string;
}
You will have to provide definitions for each function you're consuming. While this is faster, it may be a good time to reevaluate prototypes.js
and make it TypeScript friendly.
Convert the Library to typescript and import/export functions as needed. This is more time consuming, but if you own the library it's something you're going to want to do eventually.
If you wanted to update the library and still use the prototype (which doesnt treeshake well) you would do something like this:
File: string-prototypes.ts
String.prototype.trimWhiteSpaces = trimWhiteSpaces;
interface String {
trimWhiteSpaces: typeof trimWhiteSpaces;
}
function trimWhiteSpaces() {
return this.split(' ').join('');
}
At the top of your app.module.ts
import this file like so:
import './string-prototypes';
The second approach would be to structure your library like this, and import the functions as needed.
File: string-helpers.ts
export function trimWhiteSpaces(input: string) {
return input.split(' ').join('');
}
In a component:
import { trimWhiteSpaces } from './string-helpers';
You loose the prototype augmentation this way, but it guarantees consumers of your library are only using what they need.
I had the urge to prototype some methods too
We're working on a project that uses thousands of classes and members, a large amount of these members are completely repetitive and could be shared among the components
after a few minutes searching I came across these solution Angular Global or Shared Modules
this would happen to any medium to large web application
Angular Docs explained how to do so
Note that This option is different than just any ordinary global module , we want to populate some prototype with our own functionality
This Article Easily Shows how to populate prototypes for our own use inside an Angular App
You can simply declare such interface as global in a separate file and export it so that typescript knows about it.
So your file e.g. prototypes.ts should look like this:
export {}; // Using the export, there is no need to import the file anywhere.
declare global {
interface String {
trimWhiteSpaces(): string;
}
interface Array<T> {
isEmpty(): boolean;
isNotEmpty(): boolean;
}
}
if (!String.prototype.trimWhiteSpaces)
String.prototype.trimWhiteSpaces = function (): string {
return this.replace(/ +/g, '');
}
}
if (!Array.prototype.isEmpty) {
Array.prototype.isEmpty = function <T>(): boolean {
return this?.length === 0;
};
}
if (!Array.prototype.isNotEmpty) {
Array.prototype.isNotEmpty = function <T>(): boolean {
return this?.length > 0;
};
}
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