封装无导出纯JS库时,TypeScript声明文件无法导入QRCode问题
解决全局QRCode库的TypeScript声明问题
我来帮你搞定这个类型声明的坑!这个库是全局注入式的(没有ES模块导出,直接在全局作用域挂载QRCode变量),你现在的声明文件把类和模块分开处理,导致全局类型和模块导出没关联上,还有几个语法细节需要调整。
问题拆解
- 原库运行后会在全局作用域添加
QRCode类和QRCode.CorrectLevel枚举,不是通过export导出的模块 - 你写的
declare class QRCode是全局声明,但declare module部分的导出和全局类没关联 - 接口里直接写默认值是不符合TS语法的(TS接口不能定义属性默认值,默认值是库运行时处理的逻辑)
正确的声明文件写法
场景1:直接通过<script>引入库(纯全局使用)
如果你的项目是直接用脚本标签引入库,用全局变量开发,声明文件这么写:
// qrcodejs.d.ts declare global { // 对应原库的QRCode.CorrectLevel枚举 enum QRCodeCorrectLevel { L = 1, M = 0, Q = 3, H = 2 } // 配置项接口,把原库有默认值的属性设为可选 interface QRCodeOptions { text: string; width?: number; // 原库默认256 height?: number; colorDark?: string; colorLight?: string; correctLevel?: QRCodeCorrectLevel; } // 全局QRCode类,绑定静态枚举属性 class QRCode { constructor(el: HTMLElement, option: string | QRCodeOptions); makeCode(sText: string): void; clear(): void; static CorrectLevel: typeof QRCodeCorrectLevel; } } // 标记这个文件为模块,避免全局作用域冲突 export {};
场景2:通过npm安装库(用import导入)
如果你是npm安装这个包(比如包名是davidshimjs-qrcodejs),需要适配模块导出逻辑:
// davidshimjs-qrcodejs.d.ts declare enum QRCodeCorrectLevel { L = 1, M = 0, Q = 3, H = 2 } interface QRCodeOptions { text: string; width?: number; height?: number; colorDark?: string; colorLight?: string; correctLevel?: QRCodeCorrectLevel; } declare class QRCode { constructor(el: HTMLElement, option: string | QRCodeOptions); makeCode(sText: string): void; clear(): void; static CorrectLevel: typeof QRCodeCorrectLevel; } // 让模块导出这个全局类,支持import导入 declare module 'davidshimjs-qrcodejs' { export = QRCode; }
关键修正说明
- 全局作用域绑定:用
declare global把类型挂到全局,项目任何地方都能直接用QRCode - 枚举关联:给
QRCode类加static CorrectLevel属性,对应原库的QRCode.CorrectLevel全局枚举 - 接口调整:把带默认值的属性改成TS可选属性(
?),因为接口不能定义默认值,默认值是库运行时处理的 - 模块适配:用
export = QRCode让npm包支持import QRCode from 'davidshimjs-qrcodejs'导入
现在你应该能正常使用QRCode类的实例方法、静态枚举了!
内容的提问来源于stack exchange,提问作者ppavlov
相关产品推荐
相关产品推荐

