如何将JSON转换为TypeScript类型并对比两个TypeScript类型?
解决方案:JSON转TS类型/接口 + 类型一致性校验
一、JSON快速转TypeScript类型/接口
1. 编辑器快捷方式(最简便)
直接用VSCode自带功能:复制你的JSON内容,打开TS文件,按下Ctrl+Shift+P(Windows/Linux)或Cmd+Shift+P(Mac),搜索**"Paste JSON as Code"**,直接生成对应的接口/类型。比如你的示例JSON会生成:
interface RootObject { accessToken: string; logOutToken: string; }
2. 代码自动生成(批量/脚本场景)
用typescript库的API写个简单转换脚本,适合需要批量处理的场景:
import * as ts from 'typescript'; function jsonToTsType(json: string, typeName = 'Root'): string { const obj = JSON.parse(json); const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const factory = ts.factory; // 生成属性列表 const properties = Object.entries(obj).map(([key, value]) => { let typeNode: ts.TypeNode; switch (typeof value) { case 'string': typeNode = factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); break; case 'number': typeNode = factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); break; case 'boolean': typeNode = factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); break; case 'object': typeNode = Array.isArray(value) ? factory.createArrayTypeNode(factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)) // 简化数组类型处理,可按需扩展 : factory.createTypeReferenceNode(`${typeName}${key.charAt(0).toUpperCase() + key.slice(1)}`, undefined); break; default: typeNode = factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } return factory.createPropertySignature(undefined, factory.createIdentifier(key), undefined, typeNode); }); // 生成导出类型别名 const typeAlias = factory.createTypeAliasDeclaration( [factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), undefined, factory.createTypeLiteralNode(properties) ); return printer.printNode(ts.EmitHint.Unspecified, typeAlias, undefined); } // 示例调用 const jsonStr = `{ "accessToken": "justTestString", "logOutToken": "justTestString" }`; console.log(jsonToTsType(jsonStr, 'RootObject'));
二、TypeScript类型一致性校验
1. 运行时校验(用ts-morph简化AST操作)
ts-morph是封装了TS原生API的工具,能方便解析和对比类型结构:
- 先安装依赖:
npm install ts-morph --save-dev - 校验脚本:
import { Project } from 'ts-morph'; function areTypesEqual(type1Code: string, type2Code: string): boolean { const project = new Project(); const tempFile = project.createSourceFile('temp.ts', '', { overwrite: true }); // 临时添加两个类型 tempFile.addTypeAlias({ name: 'TypeA', type: type1Code }); tempFile.addTypeAlias({ name: 'TypeB', type: type2Code }); // 获取类型并对比 const typeA = tempFile.getTypeAlias('TypeA')?.getSymbol()?.getType(); const typeB = tempFile.getTypeAlias('TypeB')?.getSymbol()?.getType(); return !!typeA && !!typeB && typeA.equals(typeB); } // 示例调用 const customType = `{ accessToken: string; logOutToken: string; }`; const generatedType = jsonToTsType(jsonStr, 'RootObject').replace('export type RootObject = ', ''); console.log(areTypesEqual(customType, generatedType)); // 输出 true
2. 编译时校验(纯TS类型玩法)
如果只需要在编译阶段判断类型是否一致,可以用泛型技巧:
type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends (<G>() => G extends U ? 1 : 2) ? true : false; // 示例 type RootObject = { accessToken: string; logOutToken: string }; type GeneratedRootObject = { accessToken: string; logOutToken: string }; type CheckResult = IsEqual<RootObject, GeneratedRootObject>; // 类型为 true
内容的提问来源于stack exchange,提问作者tron21
相关产品推荐
相关产品推荐

