Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension methods in typescript (system)

In my angular2 project I'm trying to extend the prototype of the string class using typescript. This is my code:

interface String 
{
    startsWith(s:string);
    contains(s:string);
    containsOr(s1:string, s2:string);
}

String.prototype.startsWith = function (s:string):boolean {
    return this.indexOf (s) === 0;
}
String.prototype.contains = function (s:string):boolean {
    return this.indexOf(s) > 1;
}
String.prototype.containsOr = function (s1:string, s2:string):boolean {
    return this.indexOf(s1) > 1 || this.indexOf (s2) > 1;
}

With this code the project compiles (also the content assist of Visual Studio Code assists me) but at run-time I get a 'contains is not defined'.

What I'm doing wrong?

Thanks a lot

PS: this is my tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir": "wwwroot/app/source/"
  },
  "exclude": [
    "node_modules",
    "bower_components",
    "wwwroot",
    "typings/main",
    "typings/main.d.ts"
  ]
}

EDIT

I noticed that importing the js file in index.html it works, but I don't like this approach.

<script src="app/source/utils/extensions.js"></script>
like image 321
user3471528 Avatar asked Apr 05 '16 17:04

user3471528


People also ask

Does TypeScript have extension methods?

Extension-method gives you the power to add new methods to existing types. You don't have to create a new derived-type. You can write extension-method of any data-type you want.

What is extension method with example?

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.

What is extension method in LINQ?

LinqExtensionMethod.zip. Linq provides standard query operators like filtering, sorting, grouping, aggregation, and concatenations, and it has many operators to achive many types of functionalities, which are called extension methods, in LINQ.

How do I extend a class in TypeScript?

Just like object-oriented languages such as Java and C#, TypeScript classes can be extended to create new classes with inheritance, using the keyword extends . In the above example, the Employee class extends the Person class using extends keyword.


2 Answers

I was able to get it working with no TS errors (1.8.9), Angular2 (2.0.0-beta.12) errors, and working function call using the following template:

tsconfig.json

{
  "compilerOptions": {
  "target": "es5",
  "module": "system",
  "moduleResolution": "node",
  "sourceMap": true,
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "removeComments": false,
  "noImplicitAny": false
},
"exclude": [
  "node_modules",
  "typings/main",
  "typings/main.d.ts"
  ]
}

Next, create (if one doesn't exist) a global.d.ts file local to your project:

global.d.ts (local to project, not main TS file of same name)

export {}

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

extensions.ts (entire file)

export {}

//don't redefine if it's already there
if (!String.prototype.hasOwnProperty('calcWidth')) {
    String.prototype.calcWidth = function (): number {
      //width calculations go here, but for brevity just return length
      return this.length;
    }
}

Then in your whatever your first System.import(filename) is (mine is main.ts). Just use once:

import './extensions'  //or whatever path is appropriate
... 
...

Now, throughout your app you can use your interface:

var testString = 'fun test';
console.log(testString.calcWidth());

Produces console output:

8

Hope this is helpful.

like image 75
Paul M Avatar answered Oct 02 '22 07:10

Paul M


Instead of importing the code in html just put this at the top of your code:

import './utils/extensions';

Just replace it with your path to the file.

Here are some more resources on modules and imports:

TypeScript docs

MDN docs

like image 28
Luka Jacobowitz Avatar answered Oct 02 '22 09:10

Luka Jacobowitz