javascripttypescriptimportecmascript-2020

Working with native dynamic ES2020 modules in TypeScript (without Node.js) and typing things


I have a TypeScript application working with es16 modules, most of them are imported statically. I want to use a (validator-) module now that is only imported in debug mode. It's all working, but I don't understand how to type things so that I get code completion and error-checking.

in my main class in main.ts I have:

...
if(debug){
  import('./validator.js').then((module) => this.validate(module))
}
...

the validate method looks like that:

private validate(module):void{
  new module.Validator(dataToValidate);
}

validator.js contains:

export class Validator{
  coonstructor(data:MyDatatype){
     stuff going on here...
  }
}

what I would like to know/do is:

in the validate method:

private validate(module:someMeaningfulType){...}

and also I'd like to import the Validator class, without actually importing it. if I wrote

import {Validator} from './validate.ts' 

at the top of main.ts I would load the file regardles of I need it, which defeats the whole point of dynamic imports.

I might try to whrite a type declartaion for module and Validator in main.ts, but even if that wouldn't conflict somehow, I would have to manually keep it in sync with the actual module, which is not what I want - obviously.

I might miss something obvious, but I cannot find out what. I find id hard to search for the (pure) use of native es2020/2022 modules with Typescrit, as there is so much information about node-modules etc. overshadowing it.


Solution

  • You can actually use import with typeof to get the type of the imported module:

    private validate(module: typeof import("./validator.js")) { ... }
    

    Alternatively, you can use a type-only import, which will be erased in the output:

    import type * as ValidatorModule from "./validator.js";
    
    // ...
    
    private validate(module: ValidatorModule) { ... }