17

I want to add extension method format() to String. So my expectation is that I can use String.format wherever in my project. I had followed the guideline of this topic but this not help. I got this error: enter image description here

Can anyone help me?

Thanks in advance.

p.s: I want to add the extension method like I did in angular 1.xx

enter image description here


Edit

use declare global won't get error.

declare global {
interface String {
    format(): string;
}}

String.prototype.format = function () :string {
var result = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
    var reg = new RegExp("\\{" + i + "\\}", "gm");
    result = result.replace(reg, arguments[i + 1]);
}
return result;}

How we use String.format('<img alt="{0}" title="{0}" src="{1}" />', name, id); Since format does not require parameters

2
  • Whatever you have should work. Playground link Commented Apr 27, 2017 at 2:22
  • It should be mentioned that is is a terrible practice. Extendng prototypes isn't a good practice either, but String.format is not even a prototype method - the latter would have a benefit of using it like '...'.format() at least. Using globals as namespaces in TypeScript makes no sense. Use modules. If you did this in A1 and switched to A2 and TS, it looks like there's a good chance to stop doing that at last. Commented Apr 27, 2017 at 3:34

2 Answers 2

10

For me the following worked in an Angular 6 project using TypeScript 2.8.4.

In the typings.d.ts file add:

interface String {
  format(...args: string[]): string;
}

Note: No need to 'declare global'.

In a new file called string.extensions.ts add the following:

interface String {
  format(...args: string[]): string;
}

String.prototype.format = function (...args: string[]): string {
  var s = this;
  return s.replace(/{(\d+)}/g, function (match, number) {
    return (typeof args[number] != 'undefined') ? args[number] : match;
  });
};

To use it, first import it:

import '../../string.extensions';

Obviously your import statement should point to the correct path. Inside your class's constructor or any method:

console.log("Hello {0}".format("world"));
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for this, it helped me a lot. In case someone needs it, you can add a shortcut in the tsconfig.json: "paths": { "@extensions/*": [ "./*.extensions.ts" ] } and use it like this: import '@extensions/string';
nice tip on the paths @Gus
This should be the accepted answer. This works with Angular 6 and declare global isn't the best way to go about things and import is provdided specfically to avoid that.
I don't see a typings.d.ts, should I create it ? Where ? And how do I include it in the solution ?
@Robouste you can create it in the src folder. See my post on using it, i.e. "To use it, first import it"...
|
9

Based on this playground it works just fine.

It probably doesn't work for you because you're probably using modules (import/export), in that case you need to do that in the global augmentation:

declare global {
    interface String {
        foo(): number;
    }
}

Then you won't get an error when adding foo to the prototype.


Edit

Seems like you want a static function on String, so you need to do this:

declare global {
    interface StringConstructor {
        format(): string;
    }
}

String.format = function (...args: string[]) {
    ...
}

I also added the ...args: string[] to the signature which tells the compiler that the function expects any number of strings as arguments.

4 Comments

Thank you for replying. Use declare global won't get error. But how can I declare a method in typescript that I can pass any multiple parameters? declare global { interface String { format(): string; } } String.prototype.format = function() { var result = arguments[0]; for (var i = 0; i < arguments.length - 1; i++) { var reg = new RegExp("\\{" + i + "\\}", "gm"); result = result.replace(reg, arguments[i + 1]); } return result; } I could not use: String.prototype.format('<img alt="{0}" title="{0}" src="{1}" />',name, id);
1. Don't put code in comments, instead edit your question and put the code there, then simply comment on an answer and write that the question was updated, 2. Check my revised answer
As I wrote in my updated answer, you need to add the format function to the String class (StringConstructor) as static method, and not to the prototype...
Your solution is my expectation. Thank you so much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.