thomaux
thomaux

Reputation: 19718

TypeScript: extend a class that has been loaded via require

Context

We're splitting our current project (TypeScript + RequireJS) into separate modules (core, widget1, ...). We're running version 0.8.1.1 of TypeScript.

Each module is built to a single file, and the core will be loaded initially. The widgets will be lazy loaded, only in case they are needed, but I want to make sure the widgets can reference my core modules (but not include the module in their output).


To clarify when compiling TypeScript to AMD modules, import statements will be compiled into the dependency array of the module's define function. Example:

TypeScript

import coreModule = module("core");

JavaScript output (with AMD flag)

define(['require', 'exports', 'core'], function(require, exports, __CoreModule__){
    var coreModule = __CoreModule__;
});

This is exactly what I'm trying to avoid.

Hence I'm planning on replacing all import someCoreModule = module("core/..."); statements with var someCoreModule = require("core/..."); ones.

Problem

The problem I'm facing is some of these core modules are returning base classes which can be extended by the widgets. Due to the namespacing in TypeScript, this means I need to extend these as follows:

import baseClass = module("core/SomeBaseClass");
class Child extends baseClass.Base {
}

And ofcourse I still need this same syntax when replacing the import statement with a require one:

var baseClass = require("core/SomeBaseClass");
class Child extends baseClass.Base {
}

This obviously results in an error regarding a missing type (Base). I currently plan to circumvent this error by providing a stub implementation of the base class. As follows:

declare module baseClass {
    class Base {
    }
}

var baseClass = require("core/SomeBaseClass");
class Child extends baseClass.Base {
}

Although this works, I find this rather ugly looking. I need to be able to extend the class as I need calls to super. This means I can't use an interface to type the required module.

Does anyone know a better solution or am I forced to solve my issue in this way?

As always, any help greatly appreciated!

Upvotes: 2

Views: 2198

Answers (2)

basarat
basarat

Reputation: 276199

I am afraid there is no way to get the compiler to not generate the additional requirement in the define call.

When using vanilla require statements, you can try to generate a .d.ts from the ts file for you (so that you do not need to add that stub) using the --declaration compiler flag. Hope this helps.

Also sounds like a good feature to have in the compiler (and a simple one to implement I suppose), so you might want to request that here : https://typescript.codeplex.com/workitem/list/basic (send the link in a comment, I'll definitely vote for it).

Upvotes: 2

basarat
basarat

Reputation: 276199

Wrong answer. Left for context.

The problem you are trying to solve : I want to make sure the widgets can reference my core modules, but won't include these in their output file.

When you do :

import baseClass = module("core/SomeBaseClass");

and compile with the --module 'amd' compiler flag it creates a define and require call same as you are trying to achieve. It doesn't pull it in. You can see a sample I created here : https://github.com/basarat/TypeScriptEditor/tree/gh-pages/scripts

Upvotes: 0

Related Questions