58

Possible Duplicate:
How does prototype extend on typescript?

I am currently learning TypeScript, and would like to know how it is possible to add functionality to existing objects. Say I want to add an implementation for Foo to the String object. In JavaScript I would do this:

String.prototype.Foo = function() {
    // DO THIS...
}

Understanding that TypeScript classes, interfaces and modules are open ended led me to try the following, without success

1. Reference the JavaScript implementation from TypeScript

    JavaScript:

    String.prototype.Foo = function() {
        // DO THIS...
    }

    TypeScript:

    var x = "Hello World";
    x.Foo(); //ERROR, Method does not exist

2. Extend the interface

interface String {
    Foo(): number;
}

var x = "Hello World";
x.Foo(); //Exists but no implementation.

3. Extend the class

class String {
    Foo(): number {
        return 0;
    }
}

// ERROR: Duplicate identifier 'String'

As you can see from these results, so far I have been able to add the method via an interface contract, but no implementation, so, how do I go about defining AND implementing my Foo method as part of the pre-existing String class?

0

1 Answer 1

77

I have found the solution. It takes a combination of the interface and the JavaScript implementation. The interface provides the contract for TypeScript, allowing visibility of the new method. The JavaScript implementation provides the code that will be executed when the method is called.

Example:

interface String {
    foo(): number;
}

String.prototype.foo= function() {
    return 0;
}

As of TypeScript 1.4 you can now also extend static members:

interface StringConstructor {
    bar(msg: string): void;
}

String.bar = function(msg: string) {
    console.log("Example of static extension: " + msg);
}
Sign up to request clarification or add additional context in comments.

33 Comments

Exactly, that's how it is meant to be. Remember, TypeScript is not a language in itself, it is just a syntactic sugar. So writing something in 'JavaScript style' is a good practice that has no drawbacks whatsoever.
Does this solution really work with String? Because I'm doing the exact same thing and get compile errors that the property doesn't exist on the String type. What am I missing? (using tsc 1.4.1)
@OlegMihailik Aren't all langues just syntactic sugar?
@series0ne, if copypast code above, [ts] Property 'foo' does not exist on type 'String'.
In case anyone else has the same problem I did: I used the code here, and found it worked. BUT, if I use it in a module (i.e. with an export statement) then I get the error [ts] Property 'foo' does not exist on type 'String'. (in both VS Code and the playground) . The fix is to make the interface global: declare global { interface String { foo(): number; } }.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.