user448516
user448516

Reputation:

Simple extension method in TypeScript

I'm trying to create an extension method for class but seems something is wrong. Below is the code, the output JS-file is correct but the compiler twice times shows an error "test.ts(10,16): The property 'close' does not exist on value of type 'Test'" What should be corrected ?

class Test {
} 

interface Test
{
    close():any;
}

Test.prototype.close  = function() {}

var t = new Test();

t.close();

Update: The code above is compiled okay with built-in types. I need to extend my own classes.

Update 2: Old compiler version issue. Currently all is okay!

Upvotes: 6

Views: 17567

Answers (1)

Fenton
Fenton

Reputation: 250932

This example uses inheritance to extend the original object. The naming is just for illustration.

class Test {
    baseMethod() {

    }
} 

class TestWithClose extends Test {
    close() {

    }
}

var t = new TestWithClose();

t.close();
t.baseMethod();

Update

You have mentioned in your comment that you can write extension methods for built-in functions in the way you want and I can see that you want to do the same for your own code, but that isn't possible.

I hope this explains why.

When you create a declaration in TypeScript, you can extend that declaration by adding to it. You can either use the declare keyword or place the file in a .d.ts file:

For example, if you have this declaration in one file:

declare interface ExampleInterface {
    methodOne();
}

You can extend the declaration in another file:

declare interface ExampleInterface {
    methodTwo();
}

So when you use it, you have both functions available:

function example(example: ExampleInterface) {
    example.methodOne();
    example.methodTwo();
}

These aren't really extension methods - this is just telling the compiler about an implementation in more than one go. This is particularly useful for jQuery as it allows each plugin to have a definition that adds to the JQuery interface.

You can't do this for you own TypeScript code, because adding to an interface will cause all implementations to require an update to match the interface definition.

The mind-shift here is that TypeScript is giving you static typing and you are looking for dynamic behaviour - so you have to choose one or the other. For example, you can just use dynamic behaviour where you really want it and leave the rest statically typed:

class Test {
} 

// statically typed

var stTest = new Test();

// dynamically typed

var testExtender: any = Test;
testExtender.prototype.close = function() {
    alert('Close');
};

var t: any = new Test();
t.close();

That isn't to say something won't be added to the language in the future to support extension methods.

Upvotes: 6

Related Questions