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

ts-morph能否不通过文件直接操作TypeScript接口提取属性?

结论

ts-morph 不支持getKeys<InterfaceName>()这类无需关联源码文件、直接传入接口作为泛型参数的调用形式。

核心原因

ts-morph是TypeScript静态代码分析工具,所有分析能力的基础是读取磁盘存储的TS源码、构建AST语法树,它无法直接读取运行时上下文里的TS类型信息:

  • TypeScript的类型系统仅在编译阶段生效,代码编译为JS后,接口、类型别名这类类型结构会被完全擦除,泛型参数也不会保留到JS运行时,没有任何途径能在函数执行时拿到传入的泛型接口的结构信息。
  • 你当前实现里「接口必须单独存为文件、需要手动拼接路径」的限制,是使用方式不当导致的,不需要靠泛型传参就能解决。
优化实现

全局只初始化一次Project实例,直接加载项目根目录的tsconfig配置,一次性把所有项目源文件纳入分析范围,后续调用时直接在全项目范围内检索目标接口即可,完全不需要手动传入文件路径:

import { Project } from "ts-morph";
import path from "path";

// 全局复用项目实例,缓存AST结构,性能远高于每次调用新建实例
const project = new Project({
  tsConfigFilePath: path.resolve(process.cwd(), "./tsconfig.json"),
});

const getKeys = (interfaceName: string): string[] => {
  const targetInterface = project.getInterface(interfaceName);
  if (!targetInterface) {
    throw new Error(`项目中未找到名为 ${interfaceName} 的顶层接口`);
  }
  return targetInterface.getProperties().map(prop => prop.getName());
};

// 调用示例:直接传入接口名称即可,不需要关心接口所在的文件路径
const userPropertyKeys = getKeys("User");

如果想要接近泛型调用的开发体验,可以补充一层类型约束,让IDE自动补全可用接口名、传入错误名称时触发类型报错:

// 提取项目中所有导出类型的名称作为入参的合法值范围,可根据自己的项目目录调整导入范围
type ValidInterfaceName = keyof {
  [K in keyof typeof import("./types/index") as typeof import("./types/index")[K] extends Function ? never : K]: never
};

const getKeys = (interfaceName: ValidInterfaceName): string[] => {
  // 逻辑和上述实现一致
};

这种实现下,调用函数时IDE会自动提示所有合法的接口名,开发体验和直接传入泛型参数几乎没有差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:36:23