首页 > 解决方案 > 如何使用正确的“模块”为遗留 CommonJS 依赖项发出 TS 声明

问题描述

我正在尝试为我使用的旧依赖项生成类型声明,这些依赖项发出 CJS 模块并且没有自己的类型。例如,aabb-3d模块(尽管此问题并非特定于该模块)。

我正在使用如下命令生成声明:

tsc node_modules/aabb-3d/index.js 
    --allowJs 
    --declaration 
    --emitDeclarationOnly 
    --outFile types/aabb-3d/index.d.ts

这有效,并且生成了声明,但文件的内容如下所示:

declare module "index" {
    export = AABB;
    function AABB(pos: any, vec: any): AABB;
    //...

然后当我尝试编辑代码时,我的编辑器不会选择类型,因为它希望声明是声明 module aabb-3d,而不是index.

如果我手动更改生成的d.ts文件,我的编辑器可以正常工作,并且代码提示对于遗留模块也可以正常工作。如何tsc生成工作声明文件?

标签: typescripttsctype-declaration

解决方案


我检查了 TypeScript 自己的代码,没有明显的方法可以更改该declare module行的生成方式。幸运的是,您可以完全阻止它生成。您将获得环境外部模块声明 ( declare module),因为您使用--outFile的是--outDir. 以下是如何在types/aabb-3d/index.ts没有 ES 样式的模块声明的情况下生成相同的文件declare module

tsc node_modules/aabb-3d/index.js 
    --allowJs 
    --declaration 
    --emitDeclarationOnly 
    --outDir types/aabb-3d

为了让 TypeScript 在types树中找到 ES 风格的模块声明,您需要在项目的tsconfig.json:

{
    ...
    "compilerOptions": {
        ...
        "typeRoots": [
            "./types",
            "./node_modules/@types"
        ],
        "baseUrl": "./",
        "paths": {
            "*": [
                "./types/*",
                "*"
            ]
        }
        ...
    }
    ...
}

然后您可以import aabb3d from 'aabb-3d'在您的代码中输入适当的内容,例如 tsc 自动生成它时。

如果包的"main"文件未命名index.js,因此生成的声明未命名index.d.ts,则需要package.json在目录中放置一个文件以types/$package将编译器指向正确的文件。例如,如果主文件是main.js,制作声明文件main.d.tspackage.json则将是:

{
    "types": "main.d.ts"
}

推荐阅读