You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript生成.d.ts声明文件时如何排除内部导出类型?

问题描述

我正在编写一道面试题,通过创建一个「Http Client」包来模拟后端服务器。我希望部分类型能暴露在.d.ts文件中给面试者提供上下文,但绝大多数类型不能暴露,因为它们会泄露模拟服务的内部实现,还会把我希望面试者自行生成的类型提前给到他们。

src/index.ts

import myPackageExport from './my-package-export';
export * from './public-types';
export { MyPackageExport } from './my-package-export';

export default myPackageExport;

我希望可以直接在tsconfig.json和/或webpack.config.js中配置相关规则实现需求,示例配置如下:

tsconfig.json

{
  "compilerOptions": {
    // ...
    "noEmit": true, // 我也尝试过设为false
    "declaration": true,
    "emitDeclarationOnly": true,
    "rootDir": "./src",
    "outDir": "./lib",
  },
  "include": [ "./src/index.ts" ],
  // ...
}

webpack.config.js

// ...

module.exports = {
  entry: path.join(__dirname, 'src/index.ts'),
  output: {
    filename: 'index.js',
    path: path.join(__dirname, 'lib'),
  },
  // ...
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [ 'ts-loader' ],
      },
    ],
  },
  resolve: {
    extensions: [ '.js', '.ts' ],
  },
  plugins: [
    // 这里可以加声明生成相关的插件
  ],
};

但这套配置会生成index.ts整个依赖树(也就是整个项目)的声明文件,通常这是符合预期的效果,但不符合我当前的需求。要是有类似// @ts-exclude-declaration的注释可以加在要排除声明的文件头部就好了,但据我所知目前没有这样的功能。

我当前的临时解决方案是新增/修改三个文件:

src/public-types/index.ts(修改后)

export * from './my-public-types1';
// ...

export interface MyPackageExport {
  // ...
}

declare const myPackageExport: MyPackageExport;

export default myPackageExport;

tsconfig.types.json(新增)

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    // ...
    "declaration": true,
    "emitDeclarationOnly": true,
    "rootDir": "./src/public-types",
    "outDir": "./lib",
  },
  "include": [ "./src/public-types/index.ts" ],
}

package.json(修改后)

{
  "scripts": {
    "build": "webpack --mode production && tsc -p tsconfig.types.json",
    // ...
  },
  // ...
}

这个方案可以正常运行,但不够优雅,请问有没有更好的实现思路?


解决方案

给你两个更简洁的实现思路,不用维护多套tsconfig和重复的类型定义:

方案1:手动维护公开类型入口

直接关闭TS自动生成声明的能力,所有公开类型手动维护在单独的.d.ts文件里,通过package.json指定类型入口即可:

  1. 删掉tsconfig里的declaration、emitDeclarationOnly相关配置,ts-loader只负责转译TS生成JS产物
  2. 手动创建types/index.d.ts,把要公开的类型全部写在这里
  3. 在package.json中添加配置:
{
  "types": "./types/index.d.ts",
  "typesVersions": {
    "*": {
      "*": ["./types/index.d.ts"]
    }
  }
}

这种方式适合公开类型不多的场景,完全可控,不会泄露任何内部类型,维护成本也很低。

方案2:用dts-bundle-generator插件打包声明文件

如果公开类型较多,不想手动维护,可以用这个插件,它只会提取入口文件中导出的公开类型,自动把所有依赖的类型打包成单个.d.ts文件,不会暴露内部未导出的类型:

  1. 安装依赖:npm i dts-bundle-generator -D
  2. 修改package.json的build脚本:
{
  "scripts": {
    "build": "webpack --mode production && dts-bundle-generator --out-file ./lib/index.d.ts ./src/index.ts"
  }
}

不需要额外的tsconfig配置,插件会自动读取你现有的tsconfig规则,生成的产物只有一个index.d.ts,包含的全是你在入口文件导出的公开类型,内部依赖的未导出类型会被自动剔除。


内容的提问来源于stack exchange,提问作者dx_over_dt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:06:03