在 TypeScript 中使用静态类型动态加载模块的正确方法
我正在使用 TypeScript 和 WebPack。
有一个模块我需要动态加载。当前的解决方案是:
declare function require(module: string): any;
const m = require("./something");
m.f();
但这样我相比之下失去了静态类型:
import {f} from "./something";
有没有办法用我的模块类型来为动态加载的模块进行类型定义?
答案#1
我认为你想要使用的是
import * as something from './something'
something.fn()
否则请详细说明你的问题。
在 TypeScript 中有几种类型的导入
import {something} from './something' //represents a named class or function
something from './something' //represents a default export from a module
import * as something from './something' // is equivalent to let method=require("something")
请在此查看完整参考:https://www.typescriptlang.org/docs/handbook/module-resolution.html
更新
编译器检测每个模块是否在生成的 JavaScript 中被使用。如果一个模块标识符仅作为类型注解的一部分使用,而从未作为表达式使用,那么该模块将不会生成任何 require 调用。未使用引用的这种省略是一种良好的性能优化,同时也允许这些模块的可选加载。
根据文档,这可以由 systemjs、requirejs 和 node 不同地处理。
//node
If(...){let a=require('something')}
//system
If(...){require(['something'],(a))=>{...}}
答案#2
我有一个部分解决方案:
import * as Something from "something"; //this will give you access to type
if(..) {
let a: typeof Something = require("something")
}
然而,这里有一个问题,如果“something”模块有暴露的接口或类型,它们将不会作为“typeof Something”的一部分显示出来。所以如果有人能帮忙解决这个问题,那就太好了!
