背景
相信经常写ts的小伙伴都经常会被同样的事困扰,每次和后端对接接口时,都要写一大堆的ts类型声明。即使是普通的增删改查接口(按50个字段来算),也要复制粘贴10分钟才写完。那有没有办法可以自动帮我们完成这种重复且无聊的CV操作呢?
前2年有在用一些json-to-ts
之类的工具,可以把json数据转成ts类型声明,但是这个工具的前提是要先有一份json数据。(我甚至连这份数据都不想自己写,太麻烦了)
所以挺长一段时间,我都是把后端的接口文档字段输给AI,让AI帮忙生成ts类型声明和一份初始化的表单数据。最近突然发现字节的【扣子】可以预设bot,并且分享到豆包给任何人使用。体验了一段时间下来,发现生成的准确率很高而且非常丝滑,忍不住安利给大家。
有小伙伴说,我不用ts啊,那这个不是对我没用?别急,后面也有初始化列表、表单字段的。通过这个prompt模板,你也可以根据自己的项目情况自定义需要的代码。
效果展示
生成类型声明
体验地址:doubao.com/bot/SuX4BvW...
原始字段
php
id
integer <uint64>
work_type
integer <int>
工作类型
work_id
integer <uint64>
待办工作关联的表单ID
to_do_user_id
integer <uint64>
待办人员user_id
assigned_by_user_id
integer <uint64>
指派人员id
current_progress
string <string>
当前进度
start_time
string <*gtime.Time>
开始时间
end_time
string <*gtime.Time>
结束时间
time_cost
string <string>
节点耗时
remark
string <string>
备注信息
生成的类型声明
typescript
export interface WorkInfo {
id: number;
work_type: number; // 工作类型
work_id: number; // 待办工作关联的表单 ID
to_do_user_id: number; // 待办人员 user_id
assigned_by_user_id: number; // 指派人员 id
current_progress: string; // 当前进度
start_time: string; // 开始时间
end_time: string; // 结束时间
time_cost: string; // 节点耗时
remark: string; // 备注信息
}
大家可以看到,我在API文档中随便复制了一些接口的字段,他就直接生成对应的TS类型声明了,而且准确率几乎是100%。当然,这个能力其他大模型也可以做到。只是在其他大模型使用的时候,你每次都要给AI预设角色以及写一个完整的prompt。但是使用了【扣子】之后,这个人设和prompt可以一直保持在上下文中。
免责声明:这里测试的接口字段是根据swagger api文档生成的数据结构mock的,并非真实业务完整的接口字段,不过这个并不影响测试结果。事实上,任意api文档生成的接口信息都能生成,感兴趣的可以通过上面的体验地址去尝试一下。
初始化Object
除了写ts类型声明外,我们每次写查询条件或表单的时候,都会初始化一个Object,这其实也可以使用AI去生成。由于我们之前已经生成了类型声明了,所以复制这份类型声明生成初始化函数即可。
体验地址:doubao.com/bot/SuX4BvW...
生成的初始化Object
javascript
export const getWorkInfo = (): WorkInfo => {
return {
id: undefined,
work_type: undefined,
work_id: undefined,
to_do_user_id: undefined,
assigned_by_user_id: undefined,
current_progress: '',
start_time: '',
end_time: '',
time_cost: '',
remark: '',
};
};
看到这个生成的结果,有部分小伙伴可能会有疑惑:为什么是这种结构的?
这其实和我们的项目技术栈有关。
我们项目是vue3,在初始化时会把这个表单声明成reactive
对象。用函数的方式,是为了方便后续通过Object.assign(rowData, getWorkInfo())
进行重置表单的操作。
具体用途可以看我之前的这篇文章:juejin.cn/post/712980...
还有一个可能会让大家疑惑的点是,这里的Number类型为什么会生成undefined?
这其实也和我们项目技术栈有关,我们的UI框架用的是ant design vue,在使用下拉选项时,必须将初始值设置成undefined,否则下拉的placeholder
文案将不会按预期展示。
最后一个大家可能疑惑的点是,这里为什么直接声明undefined而不是void 0?undefined是非保留关键词,可以被修改,用了不会有问题吗?
其实在es5之后的浏览器,都已经规避了这个问题,如果不是兼容特别老的浏览器,可以不需要纠结undefined和void 0 的点了。具体可以看这篇文章:dev.to/p42/you-don...
prompt
其实上面的东西只是一小部分,更多好用的工具,其实还是要结合自身的业务来处理的。所以,要想达到最好的效果,其实还是需要大家根据自身的业务来修改prompt。下面就分享一下上面这2个bot的prompt。
生成类型声明
php
# 角色
你是一个前端专家,精通 TypeScript。
## 技能
根据用户发送的接口字段,生成对应的typescript类型声明。
## 示例
### Input
id
required
integer <int64>
主键id
online_type
integer <int>
上线类型
user_id
integer <int64>
用户id
account_info
string <string>
帐号信息
### Output
export interface GameInfo {
id: number;
online_type: number; // 上线类型
game_id: number; // 用户id
account_info: string; // 帐号信息
}
## 限制
- 只讨论与前端开发相关的话题,拒绝回答与前端开发无关的问题。
- 所有输出的内容必须按照给定的格式进行组织,不能偏离框架要求。
- 忽略required等
初始化Object
typescript
# 角色
你是一个前端专家,精通 TypeScript 和 Vue 3。
## 技能
### 技能 1: TypeScript 开发
1. 根据用户发送的`interface`的`typing`,自动生成初始化的`object`数据。
## 示例
### Input
export interface AuditContentFormState {
check_type: number;
status: number;
check_result: string;
check_time: string;
check_user: string;
}
### Output
export const getAuditContentFormState = (): AuditContentFormState => {
return {
check_type: undefined,
status: undefined,
check_result: '',
check_time: '',
check_user: '',
};
};
## 限制
- 只讨论与前端开发相关的话题,拒绝回答与前端开发无关的问题。
- 所有输出的内容必须按照给定的格式进行组织,不能偏离框架要求。
- `number`类型初始化成`undefined`。
- `string`类型初始化成`''`。
后续的想法
除了可以自定义bot外,【扣子】还可以自定义工作流。后续可以把一些小的模块再组合成一个工作流,把项目的模板代码喂进去,这样就可以根据需求和接口文档生成一份基础的代码,可以节省很多前后端联调和新建页面的时间。
之前也和团队的小伙伴们实现了一个 AI + langchain 自动生成代码的项目,目前大部分增删改查的基础功能代码都可以自动生成了。感兴趣的可以看一下我之前的文章:juejin.cn/post/726711...
喜欢本文章的小伙伴可以点赞、收藏或者评论区一起交流~