前因
前端使用了 Typescript 每次对接 接口的时候都需要耗费时间写类型 。如何提高生产力呢?工具去处理重复性的工作。 下面我们就来实现这个需求。
**已知 接口工具可以将参数导出成 JsonSchema **
输入:JsonSchema数据格式
{
title: "返回数据",
type: ["array", "null"],
items: {
type: "object",
properties: {
id: {
type: "number",
},
title: {
type: "string",
},
},
required: ["id", "title"],
},
}
输出:Ts 类型
type ResponseData = {
id : number
title : string
}[]|null
**JsonSchema **知己知彼
- $schema:用于指定JSONSchema的版本信息,该值由官方提供,不可乱写。该关键字可以省略。
- title:当前schema的标题信息。可以省略
- description:当前节点的描述
- type:当前节点的类型,最外层type代表json的最外层是什么样的类型。例如上方的例子中,符合该JsonSchema的json数据必需是一个JsonObject而不能是一个JsonArray
- properties:代表当前节点的子节点信息。
- required: 是一个数组类型,代表当前节点下必需的节点key。例如上方例子中,规定了json的格式必需要有id和title节点。
其他的大家就面向Search Engines编程吧
代码实现
const typeMap = {
integer: "number",
};
// JsonSchema转TS类型
const jsonschema2TsType = (obj) => {
if (obj.type instanceof Array) {
return obj.type
.map((item) =>
jsonschema2TsType({
...obj,
type: item,
})
)
.join("|");
} else {
switch (obj.type) {
case "object":
let str = "{\n";
for (let key in obj.properties) {
const item = obj.properties[key];
// description
if (item.title || item.description) {
str += `/** ${item?.title ?? ""}${item?.description ?? ""} */\n`;
}
// required
const isRequired = obj.required && obj.required.includes(key);
str += `${key}${isRequired ? "" : "?"}:${jsonschema2TsType(item)}\n`;
}
str += "\n}";
return str;
case "array":
return `${jsonschema2TsType(obj.items)}[]`;
default:
return typeMap[obj.type] ?? obj.type;
}
}
};
const json = {
title: "返回数据",
type: ["array", "null"],
items: {
type: "object",
properties: {
id: {
type: "number",
},
title: {
type: "string",
},
},
required: ["id", "title"],
},
};
console.log(`type ResponseData = ${jsonschema2TsType(json)}`);
输出结果
type ResponseData = {
id:number
title:string
}[]|null