当前位置: 首页 > 知识库问答 >
问题:

typescript - 关于对第三方库增加声明文件(d.ts) 为什么加上 export {} 会报错?

谭畅
2024-05-13

自己练习编写第三方库声明文件 遇到了几个问题 求解答
根据我了解的 包含顶级import或者export的文件都被当成一个模块
若 有export {} 是否在import 时需要按需引入类似这种 import { xx } from 'xxx' 这样引入呢? 那为什么第二种情况 不需要按需引入
若没有 则被认为是全局类型声明

declare module 'fake-progress' {    interface Options {        timeConstant: number,        autoStart?: boolean,        parent?: any,        parentStart?: any,        parentEnd?: any    }    export = FakeProgress;    class FakeProgress {        constructor(opts: Options);        progress: number;        _running: boolean;        start(): void;        end(): void;        stop(): void;        createSubProgress(opts: Options): any;        setProgress(progress: any): void;        _onInterval():void;    }}

1.第一种情况
image.png

需要这样引入 而且可以提示参数
image.png

2.第二种情况 不写export
image.png

引入
image.png

3.第三种情况 需要增加 export = FakeProgress; 不提示参数
image.png

需要这样引入才不报错
image.png

4.第四种情况 看其他人写的都会有 export {} 但加上就会报错 不是很明白
image.png

引入报错
image.png
image.png

共有1个答案

郭瀚海
2024-05-13

对于你提到的几个问题,我将逐一解释:

  1. 关于export {}:
    在TypeScript声明文件中,export {}是一个空导出,它实际上是一个技巧,用于确保该文件被视为模块而不是全局脚本。在某些情况下,它用来防止与全局变量名冲突,并允许其他模块正确地导入声明。但是,当你使用export =语法(CommonJS风格导出)时,export {}可能是不必要的,并且可能导致问题,因为它改变了文件的模块类型。
  2. 关于按需引入:
    当你使用export =语法时,你实际上是在声明一个CommonJS模块,这意味着你需要使用特定的语法来导入这个模块。在你的例子中,FakeProgress是一个类,通过export =语法导出。因此,你需要使用import * as FakeProgress from 'fake-progress'来导入整个模块,而不是使用import { FakeProgress } from 'fake-progress'。后者是ES6模块风格的导入语法,它期望FakeProgress是一个命名导出,而不是默认导出。
  3. 关于export {}报错:
    当你尝试在声明文件中同时使用export {}export =时,TypeScript编译器会报错,因为这两种导出语法是互斥的。export {}表示这是一个ES6模块,而export =表示这是一个CommonJS模块。在一个文件中混合使用这两种风格是不被允许的。

针对你的代码示例,这里是一些建议:

  • 如果你希望使用CommonJS风格的导出(export =),那么不要使用export {}
  • 当你使用export =时,导入时应该使用import * as FakeProgress from 'fake-progress'
  • 如果你希望使用ES6风格的命名导出(export class FakeProgress { ... }),那么你需要修改你的声明文件以使用这种风格,并且导入时应该使用import { FakeProgress } from 'fake-progress'

修改后的声明文件(使用CommonJS风格导出):

declare module 'fake-progress' {    interface Options {        timeConstant: number;        autoStart?: boolean;        parent?: any;        parentStart?: any;        parentEnd?: any;    }    class FakeProgress {        constructor(opts: Options);        progress: number;        _running: boolean;        start(): void;        end(): void;        stop(): void;        createSubProgress(opts: Options): any;        setProgress(progress: any): void;        _onInterval(): void;    }    export = FakeProgress;}

导入方式:

import * as FakeProgress from 'fake-progress';const progress = new FakeProgress({ timeConstant: 1000 });progress.start();

注意:在实际项目中,你可能还需要考虑库的实际模块系统(CommonJS或ES6模块)和TypeScript的配置(如moduleResolution选项),以确保声明文件与实际代码库匹配。

 类似资料:
  • d.ts文件有两种运行模式: (1)d.ts文件中包含顶层import/export 就是模块运行模式 (2)d.ts文件中不包含 import/export 就是脚本运行模式 对于下面的代码 问题 1.d.ts文件中的 属性 使用declare声明和不适用declare声明有什么区别? 我自己试了下不管有没有declare,其他ts文件中都能正常引用到。 模块模式和脚本模式下 使用declare

  • 主要内容:CalcThirdPartyJsLib.js 文件代码:,Calc.d.ts 文件代码:,CalcTest.ts 文件代码:,CalcTest.js 文件代码:,实例TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaS

  • 我正在使用的一个数据湖()有2 TB的数据和20000个文件。我想把数据集压缩成2000 GB的文件。 如果运行并写入磁盘,数据湖包含1.9 TB的数据。 如果运行并写入磁盘,数据湖包含2.6 TB的数据。 数据湖中的每个文件比预期的大0.3 GB(它们都是1.3 GB的文件,而不是1 GB的文件)。 为什么方法会增加整个数据湖的大小? 还有一个相关的问题讨论了为什么在运行聚合后数据湖的大小会增加

  • 在写nodejs文件的时候发现,明明是js文件却有类型提示,甚至按住Ctrl点击也会跳转到对应的 .d.ts 声明文件,这是为什么呢? 项目目录 package.json 现象

  • 本文向大家介绍JavaScript声明变量时为什么要加var关键字,包括了JavaScript声明变量时为什么要加var关键字的使用技巧和注意事项,需要的朋友参考一下 在JavaScript中,var用来声明变量,但是这个语法并不严格要求,很多时修改,我们可以直接使用一个变量而不用var声明它。 诸如此类。这有一个问题,比如说在代码中的某一行,我想使用的一个已声明的变量x,结果由于打字或者拼写错误