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

如何将自定义类型声明正确集成到编译后的npm包中?

如何将自定义类型声明正确集成到编译后的npm包中?

我太懂你这个烦恼了——自定义的MyTypes命名空间明明写在types.d.ts里,可编译后完全没出现在dist/index.d.ts里,导致调用foo函数时类型推断全错,明明传的是数字类型的a,TypeScript却觉得返回值是字符串对吧?

这问题的核心原因是:TypeScript在生成声明文件时,只会把被源文件实际引用到的类型合并到输出的声明中。你的types.d.ts虽然在tsconfig.json的include范围内,但index.ts里没有明确引用这个文件,TypeScript就会认为这些类型是“未使用”的,不会打包进最终的dist/index.d.ts里。

下面给你几个实用的解决办法,按现代程度排序:

方案一:用ES模块规范导出类型(推荐)

把types.d.ts改成ES模块的形式,通过import type在index.ts中引入,这是TypeScript推荐的现代方式:

  1. 修改lib/types.d.ts,给命名空间和接口加上export:
export namespace MyTypes {
  export interface Bar {
    a: string;
  }
  export interface SecondBar {
    a: number;
  }
}
  1. 在lib/index.ts顶部导入类型:
import type { MyTypes } from './types';

function foo(bar: MyTypes.Bar): string;
function foo(bar: MyTypes.SecondBar): number;
function foo(bar: MyTypes.Bar | MyTypes.SecondBar): number | string {
  if (typeof bar.a === "string") {
    return "0";
  }
  return 1;
}

const MyModule = { foo };
export default MyModule;

方案二:用三斜线指令引用类型文件(兼容旧代码)

如果不想改类型文件的结构,可以用TypeScript的三斜线指令,明确告诉编译器要引入这个类型文件:

修改lib/index.ts,在顶部添加引用指令:

/// <reference path="./types.d.ts" />

function foo(bar: MyTypes.Bar): string;
function foo(bar: MyTypes.SecondBar): number;
function foo(bar: MyTypes.Bar | MyTypes.SecondBar): number | string {
  if (typeof bar.a === "string") {
    return "0";
  }
  return 1;
}

const MyModule = { foo };
export default MyModule;

方案三:合并类型到源文件中

如果你的类型只在当前模块使用,也可以直接把MyTypes的声明移到index.ts顶部,省掉单独的types.d.ts文件:

declare namespace MyTypes {
  interface Bar {
    a: string;
  }
  interface SecondBar {
    a: number;
  }
}

function foo(bar: MyTypes.Bar): string;
function foo(bar: MyTypes.SecondBar): number;
function foo(bar: MyTypes.Bar | MyTypes.SecondBar): number | string {
  if (typeof bar.a === "string") {
    return "0";
  }
  return 1;
}

const MyModule = { foo };
export default MyModule;

验证是否解决问题

不管用哪种方案,执行tsc重新编译后,打开dist/index.d.ts,你会发现MyTypes的声明已经被包含进去了。这时候再测试test.ts:

import MyModule from "./dist";
const result = MyModule.foo({ a: 1 }); // 现在TypeScript会正确推断result为number类型

这样类型推断就完全正常啦,我之前第一次写npm包的时候也踩过这个坑,差点以为是配置错了,后来才发现是类型没被引用导致的🤣

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 09:13:06