首页
更多应用
Search
1
修改iview的标签为i-的形式而不是驼峰的形式
3,188 阅读
2
PHP微信和企业微信签名
2,937 阅读
3
在VUE中怎么全局引入sass文件
2,606 阅读
4
解决Macos下storm系列IDE卡顿的问题
2,446 阅读
5
vscode硬件占用较高解决方案
2,261 阅读
默认分类
JS
VUE
CSS
mac使用技巧
React
fastmock
登录
/
注册
Search
标签搜索
react
js
vue
vscode
nodejs
项目
代码
webpack
工具
nginx
小程序
css
fastmock
eslint
npm
typescript
http
vue-cli3
git
浏览器
fastmock技术社区
累计撰写
107
篇文章
累计收到
25
条评论
首页
栏目
默认分类
JS
VUE
CSS
mac使用技巧
React
fastmock
页面
更多应用
搜索到
4
篇与
的结果
2026-01-09
typescript提取一个对象的value作为枚举类型
在 TypeScript 中,假如你之前已经定义过一个对象,如const obj = { A: 1, B: 2, C: 3 }之后,你想定义一个函数,这个函数的入参就是上面的这个对象的值的其中一个,也就是function func(val: 1 | 2 | 3) {}此时,可以通过对象key取值方法来取obj对象的可能值作为枚举类型具体方法为步骤 1:修改对象的定义,在后面加上 as constconst obj = { A: 1, B: 2, C: 3 } as const; // 使用 `as const` 确保对象是只读的步骤 2:提取值的联合类型使用 typeof 和 keyof 提取对象的值作为联合类型:function func(val: typeof obj[keyof typeof obj]) {}解读typeof obj 获取 obj 的类型。keyof typeof obj 获取 obj 的所有键(即 "A" | "B" | "C")。typeof obj[keyof typeof obj] 获取 obj 的所有值的联合类型(即 1 | 2 | 3)。上面的代码有两个关键as const:将对象标记为只读,确保 TypeScript 推断出具体的字面量类型(如 1 而不是 number)。typeof MODES[keyof typeof MODES]:通过索引访问对象的值类型,生成联合类型 1 | 2 | 3。扩展:提取键的联合类型如果你还需要提取键的联合类型(如 "A" | "B" | "C"),可以这样做:type ModeKeys = keyof typeof MODES;总结通过 typeof 和 keyof,你可以轻松提取对象的键或值的联合类型。这种方法非常适合将常量对象转换为枚举类型,同时保持类型安全。如果你有其他问题,欢迎随时提问!
2026年01月09日
4 阅读
0 评论
0 点赞
2024-12-24
vscode 打开ts文件没有了代码补全和错误提示右下角报错The JS/TS language service immediately crashed 5 times. The service will not be restarted.
更新了vscode的版本到最新版本,突然就不能愉快地编写ts代码了,具体表现为 - 使用对象里面的方法无法提示了 - 方法没有函数注释的提示,没有参数提示了,看不到参数类型和返回值类型了 - 无法 cmd+鼠标左键跳转方法或对象定义
2024年12月24日
275 阅读
0 评论
1 点赞
2024-09-14
处理TS类型声明文件,保留指定key的类型声明
我的原始需求是这样的,写了一个nodejs命令行工具,工具的功能是,拉取后端接口导出的 postman.json 接口内容,通过接口中的入参出参数据,生成入参出参的TS类型声明文件,达到在ts业务代码中可以校验接口入参和出参类型的目的,postman.json的大致格式如下{ "item": [ { "item": [ { "item": [], "name": "WechatMiniAppNatureController", "description": "WechatMiniAppNatureController" } ], "name": "wpe-miniwe-recycle-srv-api", "description": "exported at 2024-09-09 15:17:40" }, { "item": [ { "item": [ { "request": { "method": "POST", "description": "", "header": [ { "key": "Content-Type", "value": "application/json", "type": "text", "description": "" } ], "body": { "mode": "raw", "options": { "raw": { "language": "json" } }, "raw": "{\n \"Id\": 0\n}" }, "url": { "path": [ "wechat", "rec", "v1", "nature", "apply", "taxRebateInfo" ], "query": [], "host": "{{wpe-miniwe-recycle-srv-web}}", "raw": "{{wpe-miniwe-recycle-srv-web}}/wechat/rec/v1/nature/apply/taxRebateInfo" } }, "response": [ { "name": "退税申请详情接口-Example", "originalRequest": { "method": "POST", "description": "", "header": [ { "key": "Content-Type", "value": "application/json", "type": "text", "description": "" } ], "body": { "mode": "raw", "options": { "raw": { "language": "json" } }, "raw": "{\n \"Id\": 0\n}" }, "url": { "path": [ "wechat", "rec", "v1", "nature", "apply", "taxRebateInfo" ], "query": [], "host": "{{wpe-miniwe-recycle-srv-web}}", "raw": "{{wpe-miniwe-recycle-srv-web}}/wechat/rec/v1/nature/apply/taxRebateInfo" } }, "code": 200, "_postman_previewlanguage": "json", "header": [ { "name": "date", "key": "date", "value": "周一, 09 9月 202415:17:40 GMT", "description": "The date and time that the message was sent" } ], "body": "{\n \"Response\": {\n \"RequestId\": \"\",\n \"Error\": {\n \"Code\": \"\",\n \"Message\": \"\"\n },\n \"Data\": {\n \"id\": 0,\n \"taxRebateNumber\": \"\", //退税申请序号\n \"natureRecordId\": \"\", //自然人档案号\n \"registryNumber\": \"\", //登记序号\n \"collectionItemCode\": \"\", //征收项目代码\n \"collectionItemName\": \"\", //征收项目名称\n \"collectionCode\": \"\", //征收品目代码\n \"taxBureauCode\": \"\", //主管税务所科分局代码\n \"taxAuthorityCode\": \"\", //主管税务机关代码\n \"taxAmountAuthorityCode\": \"\", //税款所属税务机关代码\n \"taxAmountAuthorityName\": \"\", //税款所属税务机关名称\n \"streetTownCode\": \"\", //街道乡镇代码\n \"taxAmount\": 0.0, //应退税额\n \"taxRate\": 0.0, //税率\n \"taxUuid\": \"\", //税票UUID\n \"eleTaxNumber\": \"\", //电子税票号码\n \"taxStartTime\": \"\", //税款所属期起\n \"taxEndTime\": \"\", //税款所属期止\n \"applyStatus\": 0,\n \"rebateStatus\": \"\",\n \"rebateStatusCn\": \"\",\n \"taxStatus\": 0,\n \"rejectReason\": \"\",\n \"bankCardNo\": \"\",\n \"createTime\": \"\"\n }\n }\n}" } ], "name": "退税申请详情接口" } ], "name": "WechatMiniAppTaxController", "description": "WechatMiniAppTaxController" }, { "item": [ { "request": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json", "type": "text", "description": "" } ], "body": { "mode": "raw", "options": { "raw": { "language": "json" } }, "raw": "{\n \"QrId\": \"\"\n}" }, "url": { "path": [ "wechat", "rec", "v1", "operator", "inviteConfirm" ], "query": [], "host": "{{wpe-miniwe-recycle-srv-web}}", "raw": "{{wpe-miniwe-recycle-srv-web}}/wechat/rec/v1/operator/inviteConfirm" } }, "response": [ { "name": "operatorInviteConfirm-Example", "originalRequest": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json", "type": "text", "description": "" } ], "body": { "mode": "raw", "options": { "raw": { "language": "json" } }, "raw": "{\n \"QrId\": \"\"\n}" }, "url": { "path": [ "wechat", "rec", "v1", "operator", "inviteConfirm" ], "query": [], "host": "{{wpe-miniwe-recycle-srv-web}}", "raw": "{{wpe-miniwe-recycle-srv-web}}/wechat/rec/v1/operator/inviteConfirm" } }, "code": 200, "_postman_previewlanguage": "json", "header": [ { "name": "date", "key": "date", "value": "周一, 09 9月 202415:17:40 GMT", "description": "The date and time that the message was sent" } ], "body": "{\n \"Response\": {\n \"RequestId\": \"\",\n \"Error\": {\n \"Code\": \"\",\n \"Message\": \"\"\n },\n \"Data\": false\n }\n}" } ], "name": "operatorInviteConfirm" } ], "name": "WechatMiniAppOperatorController", "description": "WechatMiniAppOperatorController" } ], "name": "wpe-miniwe-recycle-srv-web", "description": "exported at 2024-09-09 15:17:40" } ], "info": { "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", "name": "wpe-miniwe-recycle-srv-20240909151740", "description": "exported at 2024-09-09 15:17:40" } }上面的接口文档中 接口地址为 /wechat/rec/v1/nature/apply/taxRebateInfo 的接口返回体,经过数据反解析后输出的Ts类型声明代码为export type TWechatRecV1NatureApplyTaxRebateInfoRess = { Code: number; Error: { Code: number; Message: string; }, RequestId: string; Data: { id: number; taxRebateNumber: string; natureRecordId: string; // ... 其他属性 } };上面的代码中,除了Data内的数据,其他的都是所有接口相同的属性内容,所以我需要处理生成的ts文件,只保留 Data 的类型描述。也尝试过好几种方案,主要有从源代码处理,在postman文件的response -> body 代码中处理完内容再去做反解析在生成的文件中通过字符串匹配去查找上面的方法中,主要都存在一个问题,就是postman源代码中,body包含了很多杂七杂八的内容,比如换行符,注释,还有转译字符,加上body内容的层级是不固定,这为我们做正则匹配带来了很多麻烦,所以兜兜转转想到了最终的解决方案,那就是使用AST的方法来处理生成的TS代码,这样在操作AST的过程中,babel 会帮我们处理好注释和其他不相关的内容。先show一下最终的代码// 要先安装下面的依赖 const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; /** * 取出声明代码中指定key的interface代码 * 使用babel的抽象语法树转换,处理,生成代码 * @param typeCode ts代码 * @param rootName 根类型名 * @param keyName 属性名 * @returns 取出的代码 */ export const subInterfaceByKey = (typeCode: string, rootName: string, keyName: string): string => { // 从ts类型声明代码中取出指定key的interface代码,现将代码转换成ast const ast = parser.parse(typeCode, { sourceType: 'module', plugins: ['typescript'] }); let titleType = 'any'; // 从ast中找到指定key的接口,生成代码返回。 traverse(ast, { TSInterfaceDeclaration(path) { if (path.node.id.name === rootName) { const properties = path.node.body.body; const titleProperty = properties.find(prop => prop.key.name === keyName); // console.log(titleProperty.typeAnnotation); if (titleProperty) { titleType = generate(titleProperty.typeAnnotation).code; } } }, }); if (titleType !== 'any') { // 去掉类型前面的冒号和空格 return titleType.replace(/:\s/, ''); } return titleType; };上面的代码中,通过babel parser将要处理的代码转换成ast,然后通过 traverse 的 TSInterfaceDeclaration 勾子来处理ts interface 类型的代码,最后将处理后的代码生成好赋值给变量返回,处理后的声明文件内容就成了下面这个样子了export type TWechatRecV1NatureApplyTaxRebateInfoRess = { id: number; taxRebateNumber: string; natureRecordId: string; // 。。。其他属性 };至于为什么要用type而不是interface,原因是,Data 数据有可能不是一个对象,而是基础数据类型或数组,比如export type TWechatRecV1JodCancelCmbcBillRess = boolean;经过这次经验,我想以后再遇到这种代码处理的需求,我不会第一时间想到通过正则来处理,而是通过AST来处理了,即安全又逻辑清晰,
2024年09月14日
80 阅读
0 评论
1 点赞
2023-09-12
vscode编写vue3项目代码提示缓慢问题处理
在使用vscode + volar开发vue3项目时,开发了一段时间,尤其是在新建了很多次vue文件后,编辑器就会出现代码自动补全或者错误提示缓慢,或者根本不能提示的问题,每次遇到这种情况都要通过重启vscode或者 reload window 来解决,非常的头疼。试了很多方式来解决,最后网上找到通过开启Volar Takeover *模式解决。Vue3官网 https://cn.vuejs.org/guide/typescript/overview.html#volar-takeover-mode 有关于 Volar Takeover 的详细介绍,为了优化性能,Volar 提供了一个叫做“Takeover 模式”的功能。在这个模式下,Volar 能够使用一个 TS 语言服务实例同时为 Vue 和 TS 文件提供支持。要开启 Takeover 模式,你需要执行以下步骤来在你的项目的工作空间中禁用 VSCode 的内置 TS 语言服务:在当前项目的工作空间下,用 Ctrl + Shift + P (macOS:Cmd + Shift + P) 唤起命令面板。输入 built,然后选择“Extensions:Show Built-in Extensions”。在插件搜索框内输入 typescript (不要删除 @builtin 前缀)。点击“TypeScript and JavaScript Language Features”右下角的小齿轮设置图标,然后在下拉菜单中选择“Disable (Workspace)”。重新加载工作空间(重启vscode或者reload window)。Takeover 模式将会在你打开一个 Vue 或者 TS 文件时自动启用。
2023年09月12日
672 阅读
0 评论
0 点赞