3

I have some TypeScript code that is being generated by a tool. I'd like to extend this class in another file. As of 0.9.1.1, what's the best way to go about this?

I thought maybe I could staple my additional functions onto the prototype, but this is giving various errors (which change depending what mood the compiler is in).

For example:

Foo.ts (generated by a tool)

module MyModule {
    export class Dog { }
}

Bar.ts

module MyModule {
    function bark(): string {return 'woof';}

    Dog.prototype.bark = bark;
}
MgSam
  • 12,139
  • 19
  • 64
  • 95
  • 1
    I interpret your question as meaning that you want something akin to partial classes in C#: a single class, but with a definition which spans multiple files. Some properties and methods would be defined in one file (the file generated by a tool), and some would be defined in another file, but would be members of the _same_ class, not a child class. Is this correct? If so, I don't believe there is any way to do _precisely_ this in TypeScript (see http://typescript.codeplex.com/workitem/933). – Peter Aug 28 '13 at 02:54
  • You want to dynamically extend a base class outside of the base class's definition. This seems to go against the spirit of TypeScript which is to enforce stronger typing to JavaScript. What you want to do is idiomatic JavaScript, but something that TypeScript is invented to *avoid*. Allowing types to *morph* sort of goes against the principle of strong typing... – Stephen Chung Aug 29 '13 at 04:06
  • possible duplicate of [How do I split a TypeScript class into multiple files?](http://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files) – xmojmr Sep 23 '14 at 20:11

2 Answers2

1

You cannot split a class definition between multiple files in TypeScript. However typescript understands how JavaScript works and will let you write idomatic JavaScript classes just fine:

module MyModule {
     export function Dog(){};
}

module MyModule {
    function bark(): string {return 'woof';}
    Dog.prototype.bark = bark;
}

Try it online

One way around this is to use inheritance:

class BigDog extends Dog{
     bark(){}
}
basarat
  • 261,912
  • 58
  • 460
  • 511
  • 1
    I'd rather not use a subclass. This is not an "is a" relationship. Such a solution is even more problematic without abstract classes in the language, as it leaves no clear indication which is the "real" class. – MgSam Aug 28 '13 at 12:49
  • @MgSam There is now abstract classes in TypeScript. – Alex Nov 18 '15 at 12:42
0

I have encountered your problem as well before, but I had some deeper problems. You can see from basarat's example, that simple functions can be added as an extension to the prototype, but when it comes to static functions, or other static values you might want to extend your (presumably third party) class, then the TSC will warn you, that there is no such method defined on the class statically.

My workaround was the following little hack:

module MyModule {
     export function Dog(){};
}

// in the other file
if (typeof MyModule !== 'undefined'){
    Cast<any>(MyModule.Dog).Create = ()=>{return new Dog();};
}

// where Cast is a hack, for TS to forcefully cast types :)
Cast<T>(element:any):T{ return element; } 

This should cast MyModule.Dog, to an any object, therefore allowing attachment of any kinds of properties, functions.

Alex
  • 259
  • 3
  • 7