What's the correct way to use requireJS with typescript?

前端 未结 4 2026
闹比i
闹比i 2020-12-25 11:29

The examples I have found here and here say to use module(). However, when I compile I get \"warning TS7021: \'module(...)\' is deprecated. Use \'require(...)\' instead.\"

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-25 11:44

    I have been playing with typescript, trying to integrate it in our existing javascript/requirejs project. As setup, I have Visual Studio 2013 with Typescript for vs v 0.9.1.1. Typescript is configured (in visual studio) to compile modules in amd format.

    This is what I have found works for me (there might be a better way of course)

    1. Use amd-dependency to tell the typescript compiler adds the required module to the list of components which must be loaded
    2. In the constructor of the class being exported, use requirejs’s require function to actually fetch the imported module (at this point this is synchronous because of the previous step). To do this you must reference require.d.ts

    As a side note, but since it is in my view essential to typescript, and because it gave me a bit of a headache, in the example I show two ways to export classes which use interfaces. The problem with interfaces is that they are used for type checking, but they produce no real output (the generated .js file is empty), and it causes problems of the type ‘’export of a private class” I have found 2 ways of exporting classes which implement an interface:

    1. Simply add an amd-dependency to the interface (as is in the Logger.ts file) And export a typed variable holding a new instance of the class The exported class can be consumed directly (ie myClass.log(‘hello’));
    2. Don’t add the amd- dependency to the interface (as is in the Import.ts file) And export a function (ie Instantiate()) which returns a variable of type any holding a new instance of the class The exported class can be consumed via this function (ie myClass.instantiate().log(‘hello’))

    It seems like the first option is better: you don’t need to call the instantiate function, plus you get a typed class to work with. The downside is that the [empty] interface javascript file does travel to the browser (but it’s cached there anyway, and maybe you are even using minification in which case this does not matter at all).

    In the next blocks of code there are 2 typescript modules loaded with requires (amd): Logger and Import.

    ILogger.ts file

    interface ILogger {
        log(what: string): void;
    }
    

    Logger.ts file

    ///
    
    //this dependency required, otherwise compiler complaints of private type being exported
    ///
    
    class Logger implements ILogger {
            formatOutput = function (text) {
                return new Date() + '.' + new Date().getMilliseconds() + ': ' + text;
            };
    
            log = function (what) {
                try {
                    window.console.log(this.formatOutput(what));
                } catch (e) {
                    ;
                }
            };
    }
    
    //this approach requires the amd-dependency above for the interafce
    var exportLogger: ILogger = new Logger();
    export = exportLogger;
    

    Using Logger.ts in another ts file(Import.ts)

    ///
    
    ///
    ///
    
    class _Import implements IImport{
        ko: any;
        loggerClass: ILogger;
    
        constructor() {
            this.ko = require('knockout');//require coming from require.d.ts (in external_references.ts)
            this.loggerClass = require('Shared/Logger');
        }
    
        init(vm: any) {
            this.loggerClass.log('UMF import instantiated...');
        }
    }
    
    ////Alternative Approach:
    ////this approach does not require adding ///
    ////this can be consumed as .instantiate().init();
    //export function instantiate() {
    //    var r : any = new _Import();// :any  required to get around the private type export error
    //    return r;
    //}
    
    //this module can be consumed as .init();
    var exported: IImport = new _Import();
    export = exported;
    

    IImport.ts file

    interface IImport {
        init(vm: any): void;
    }
    

    To consume the Import module straight from javascript use something like (sorry I have not tried this one, but it should work)

    define (['Import'], function (import)
    {
        //approach 1
        import.init();
    
        ////approach 2
        //import.instantiate().init();
    });
    

提交回复
热议问题