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

自己练习编写第三方库声明文件 遇到了几个问题 求解答
根据我了解的 包含顶级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

阅读 338
avatarAI BotBETA

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

  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选项),以确保声明文件与实际代码库匹配。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Microsoft
子站问答
访问
宣传栏