如何在.d.ts中通过JSON文件动态生成TypeScript联合类型?
解决方案
核心问题是TypeScript类型系统是静态的,运行时的遍历操作没法让TS推导精确的联合类型,得用预生成脚本把动态的JSON数据转成静态的类型定义:
1. 写Node.js脚本生成静态类型文件
创建一个生成脚本(比如generate-model-types.js),读取你的Schema JSON,提取模型名后直接输出带as const的类型文件:
const fs = require('fs'); const path = require('path'); // 替换成你的Schema JSON路径 const schema = require('./schema-lims.json'); // 提取并过滤模型名称,根据你的实际结构调整逻辑 const modelNames = schema.data.__schema.types .map(type => type.name) // 这里可以加过滤规则,比如排除系统内置类型 .filter(name => !name.includes('__')); // 生成.d.ts内容 const typeContent = ` export const models = ${JSON.stringify(modelNames)} as const; export type ModelName = typeof models[number]; export type FragArray = [ModelName, string]; `; // 写入到目标.d.ts文件 fs.writeFileSync(path.resolve(__dirname, './model-types.d.ts'), typeContent.trim());
2. 集成到开发流程
在package.json里加个脚本方便执行:
{ "scripts": { "generate-types": "node generate-model-types.js" } }
每次Schema JSON更新后,跑npm run generate-types就能自动更新类型定义。
3. 在项目中使用生成的类型
在你的主.d.ts文件里引入即可:
import type { ModelName, FragArray } from './model-types';
为什么之前的方案无效?
你用forEach往数组里push值的操作是运行时行为,TypeScript没法追踪每个push进去的具体字符串值,只能把models推断成string[],所以typeof models[number]就是宽泛的string类型,没法得到精确的联合类型。而静态定义的["containerArray", "aliquot"] as const会让TS把数组识别为只读的字符串元组,从而推导出精确的联合类型。
内容的提问来源于stack exchange,提问作者tgreen
相关产品推荐
相关产品推荐

