前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库npm 包 TypeScript types exports 声明入口配置
TyTypeScript类型工程

发布 TypeScript 类型包时,types、exports 和声明文件应该怎样对应?

类型入口不是一个看起来合理的路径,它必须指向用户安装后真正存在且语义匹配的声明。

前端进阶之旅 · 一题精讲更新于 2026.09.06
TypeScript#类型工程#类型系统
先看核心答案读代码示例
理解线索

让安装后的两个入口对齐

  1. 运行入口JavaScript 文件提供真实导出和行为
  2. 类型入口声明文件描述这些导出的准确契约
  3. 发布清单保证入口及其相对依赖都实际进入安装包

下面是只发布 ESM 的简单包示例,不是同时兼容 ESM 与 CommonJS 的完整双格式配置。

核心回答

先记住这个答案

package.json 的 types 指向包内主声明文件,运行时入口则由 main 或 exports 等规则提供,两者应描述同一组公开 API。使用支持 exports 的模块解析模式时,应在相应导出条件中明确提供类型入口,并让 types 条件出现在适合的优先位置;根 types 不能自动补齐所有子路径。typesVersions 用于按 TypeScript 版本选择声明,但读取 exports 的解析场景不会再读取该字段。最终应检查真实打包文件,并在独立消费者里验证类型解析与运行时导入,不能只在源码仓库中测试。

  • 类型路径与运行入口要对应同一个公开模块
  • exports 子路径和条件需要各自完整描述
  • 发布产物与独立消费测试比源码目录存在更有证明力

先把单一入口的路径和模块格式写清楚

包根目录、源码目录和最终 dist 是不同位置,types 应相对于 package.json 指向实际分发的声明。若 JavaScript 已迁移到 dist,而 types 仍指向未打包的 src,开发时可能偶然可用,安装后就会丢失类型。

示例用 type: module 表示 .js 的模块语境,并给根导出提供 types 与 default 条件。files 收集 dist,但它不会执行编译,入口文件仍需先生成。声明里的相对引用也要存在于发布集合,不能只检查 index.d.ts 这一份文件。

一个单一 ESM 包的运行与类型入口JSON
{
  "name": "typed-greeting-kit",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "files": ["dist"]
}

支持类型条件的 TypeScript 解析器可选择声明,普通运行时可选择 JavaScript。此配置没有声明任何额外子路径,也没有提供独立 CommonJS 入口;消费者不能据此假定任意深层文件都属于公开 API。

exports 与版本选择需要按真实解析模式理解

现代模块解析会按照 exports 匹配入口和条件,未开放的子路径可能被阻止。根 types 并不意味着包内所有文件都可导入,也不能修复子路径缺失声明。应为公开子入口配置一致的运行文件与类型文件,并核对扩展名和模块格式。

typesVersions 可以为不同编译器语法版本选择不同声明集合,但不能假设它与 exports 永远同时参与。官方模块解析规则明确区分这些场景;如需在 exports 下提供版本化类型条件,应采用该模式实际支持的机制并用目标编译器验证。

检查安装产物而不是只检查仓库源码

发布前查看真实包文件列表,再在独立消费目录解析包名,能发现漏打包、错误大小写和相对类型依赖缺失。测试环境应尽量不继承开发仓库的 paths 别名,否则消费者可能绕过发布入口直接读取源码,掩盖入口配置错误。

公开声明依赖的外部类型也需要在消费者环境可用。升级 TypeScript 语法或模块格式时,应按承诺支持的版本分别验证;源码 tsc 通过只能证明生产方能编译,不能证明所有承诺的消费方式都成立。

回答前,多想一步

容易答错的地方

types 指向源码就能保证用户获得类型
源码可能没有进入发布清单,且路径别名与构建目录在用户环境不同;应指向真实分发的声明并验证完整依赖闭包。
有根 types 就不需要给 exports 子路径配类型
每个公开子路径有自己的解析过程,根入口不能自动描述全部子模块;必须核对对应声明、运行文件和条件是否完整。
试着用自己的话回答

面试官还会怎么问?

typings 和 types 有什么关系?

它们都是主声明入口字段,types 是常见写法。无论使用哪个名称,关键仍是路径真实存在、模块格式匹配且声明描述实际导出。

ESM 和 CommonJS 可以共享同一份声明吗?

要结合导出形状与解析语境判断,双格式包经常需要分别匹配的声明入口和扩展名。不能只复制一个路径就承诺所有加载方式都兼容。

修改 files 字段会自动生成 dist 吗?

不会,它只参与包文件收集。编译和声明生成必须由构建流程完成,再检查实际打包结果,避免发布只有入口配置却缺少文件的包。

从一道题,走向一组知识

把知识连起来

类型工程

为什么输入的 .d.ts 不会被 tsc 编译成 JavaScript,也不会自动复制到 dist?

发布清单还需收集 tsc 不会自动复制的手写声明

类型工程

TypeScript declarationMap 怎样支持跳转源码,为什么发布后仍可能只打开 .d.ts?

希望消费者跳转源码时还需正确分发声明映射

类型工程

TypeScript 开启 declaration 后出现 TS4023,为什么类型检查通过却生成不了声明?

公开声明生成失败时要修复无法表达的类型依赖

参考资料

  • TypeScript:Publishing
  • TypeScript:Module package resolution

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 先把单一入口的路径和模块格式写清楚
  3. exports 与版本选择需要按真实解析模式理解
  4. 检查安装产物而不是只检查仓库源码
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑