背景:TypeScript会检查您尝试导入的模块,如果使用的字符串文字与实际模块的名称或支持的文件类型的路径不匹配,则会在编译时失败。
例如,import {Component} from 'react'
和import item from './item'
编译良好,但假设项目中安装了react
模块和item.ts
文件,但项目中没有安装reactt
模块和扩展名为.ts、.js、.json等的./otem
文件,则import {Component} from 'reactt'
和import item from './otem'
将无法编译。
问题:我不知道如何创建一个函数,其中一个参数是字符串文字,必须与实际模块或支持的文件相对应。
function customImportEffect(moduleName: module_string_literal) {
...
}
当'reactt'
或'./otem'
等不正确的输入被提供为参数时,module_string_literal
应该是什么类型才能使编译时检查失败?
询问原因:我正在尝试制作一个webpack文件转换器(也称为加载器(,它在TypeScript文件被转换之前将代码添加到文件的顶部,这样用户就可以使用类型安全的热模块重新加载代码。例如,假设在将以下代码转换为JS之前,将其插入每个typescript文件的上方:
class HotModule {
public static accept(moduleName: module_string_literal, onModuleReplace: Function(updatedModule: typeof import(moduleName)):void) {
if(module.hot) {
module.accept(moduleName.toString(), function() {
onUpdate(require(moduleName.toString()))
}
}
}
}
然后热模块重新加载可以是类型安全的,并且看起来更干净。假设的默认导出/item.ts文件是一个成员为message
的对象,可以编写
HotModule.accept("./item", ({message: newMessage}) => {
const oldMessage = message;
messages[messages.indexOf(oldMessage)] = message = newMessage;
}
实现消息的热重新加载,而不是
if(module.hot) {
module.hot.accept("./item", function() {
const oldMessage = message;
messages[messages.indexOf(oldMessage)] = message = require("./item");
}
}
我希望这可能是可能的,因为自从TypeScript v2.4以来,就可以异步动态导入模块,并且会检查提供的字符串文字的正确性,而不正确的字符串文字会导致编译时失败。
目前,我只是在tsconfig.json
文件的compilerOptions
对象中包含"types": ["webpack-env"]
,但我想要一个热模块API,它可以更好地利用TypeScript的检查工具集。
在某个地方制作一个带有内容的模块类型.d.ts
import json from "./package.json" // or whereever your package json is
export type ModuleName=keyof typeof json["dependencies"]
您需要在tsconfig 中启用jsonmodule
"resolveJsonModule": true,
然后你把它导入任何你需要的地方