如何在TypeScript的declare module中实现否定匹配规则
解决TypeScript中
.renderer.pug与.pug模块声明冲突的问题 你遇到的是TypeScript模块声明的匹配优先级问题——宽泛的*.pug声明会覆盖更具体的*.renderer.pug,导致TS无法区分两种模块类型。无需修改文件命名规范,通过调整模块声明的写法即可解决:
方案一:使用Glob排除语法
利用TypeScript支持的Glob模式排除规则,让普通.pug声明仅匹配非.renderer.pug的文件:
// 先声明更具体的 .renderer.pug 模块 declare module "*.renderer.pug" { const renderer: (templateVariables: unknown) => string; export default renderer; } // 声明所有不以 .renderer.pug 结尾的 .pug 模块 declare module "*!(.renderer).pug" { const HTML_Template: string; export default HTML_Template; }
Glob模式*!(.renderer).pug会匹配所有.pug结尾,但文件名中.pug前不是.renderer的文件,避免与*.renderer.pug的声明冲突。
方案二:使用模板字面量类型(TS 4.1+)
通过TypeScript的模板字面量类型精确区分两种模块,类型安全性更高:
// 定义两种模块的路径类型 type RendererPugModule = `${string}.renderer.pug`; type PlainPugModule = Exclude<`${string}.pug`, RendererPugModule>; // 声明 .renderer.pug 模块 declare module RendererPugModule { const renderer: (templateVariables: unknown) => string; export default renderer; } // 声明普通 .pug 模块 declare module PlainPugModule { const HTML_Template: string; export default HTML_Template; }
这种写法会让TS精确识别:以.renderer.pug结尾的文件对应函数模块,其余.pug文件对应字符串模块。
两种方案都无需改动现有文件命名,仅需调整TypeScript的模块声明即可实现需求。
内容的提问来源于stack exchange,提问作者Takeshi Tokugawa YD
相关产品推荐
相关产品推荐

