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

如何在TS/JS/Node.js中获取类/接口对应的定义文件路径

结论

纯原生JS/TS运行时做不到你要的完整效果,但靠编译期工具、运行时环境API可以实现接近甚至完全符合需求的功能,核心限制和可落地的方案如下:

核心限制
  • TS的接口是纯类型概念,编译成JS之后直接就被抹掉了,运行时根本没有接口这个东西,不可能当参数传给运行时的函数,所有纯运行时的方案天生查不了接口。
  • JS里的类本质就是个构造函数,本身没带任何“我定义在哪个文件”的内置信息,光拿到类的引用,原生API查不到它的来源路径。
可行实现方案

1. Node.js下凑合用的运行时方案(仅支持类)

Node.js的CommonJS模块会把所有加载过的模块存在缓存里,你可以遍历整个缓存,挨个对比模块导出的内容是不是你传入的类,匹配到了就返回对应模块的路径,代码示例:

import path from 'node:path';

function getPath(target: new (...args: any[]) => any): string | null {
  for (const modulePath of Object.keys(require.cache)) {
    const mod = require.cache[modulePath];
    if (!mod.exports) continue;
    // 匹配默认导出
    if (mod.exports === target) {
      return "./" + path.relative(process.cwd(), modulePath).replaceAll("\\", "/");
    }
    // 匹配具名导出
    for (const key of Object.keys(mod.exports)) {
      if (mod.exports[key] === target) {
        return "./" + path.relative(process.cwd(), modulePath).replaceAll("\\", "/");
      }
    }
  }
  return null;
}

这个方案问题不少:

  • 查不了接口
  • 如果类被别的文件重新导出,很可能返回的是重导出文件的路径,不是类最开始定义的文件路径
  • 只能在CommonJS环境用,ESM、打包压缩后的线上环境基本用不了

2. 构建阶段注入元数据(仅支持类)

可以给Vite/Webpack这类构建工具写个简单插件,编译的时候扫一遍所有源文件的导出,给每个导出的类加个自定义静态属性存源文件路径,比如编译后自动给Builder类加上Builder.__sourcePath = "./src/builder",运行时的getPath直接读这个属性就行。
这个方案性能比遍历缓存好,打包后也能用,但还是解决不了接口查询的问题。

3. 编译期宏替换(完全符合需求,支持类+接口)

这是唯一能完美达到你预期的方案:靠TS自定义转换器、Babel宏这类工具,在代码编译的阶段静态分析AST,遇到getPath(XXX)的调用时,直接顺着当前文件的导入声明找XXX是从哪个路径导进来的,然后把整个getPath(XXX)的调用直接替换成对应路径的字符串。
比如你源码里写的:

const path = getPath(Builder)

编译完直接变成:

const path = "./src/builder"

这个方案完全不靠运行时逻辑,不管你传的是类(实际存在的值)还是接口(纯类型),编译阶段都能分析到它的来源路径,直接替换成最终结果,和你要的效果一模一样。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:09:17