当前位置: 首页 > news >正文

uni-app 微信小程序开发:TypeScript 常用语法总结

目录

1. 基础类型声明

2. 接口与类型别名

3. 联合类型与字面量类型

4. 泛型 - 封装网络请求

5. 枚举

6. Vue 组件 Props 的类型定义

7. Composition API 与 Ref 的类型

9. 高级工具类型(Pick / 交叉类型)- 复杂表单参数的组装

8. 类型断言 - 初始化空对象与类型转换

9. uni-app/微信小程序原生 API 的类型

在 uni-app 微信小程序项目开发中,使用 TypeScript (TS) 相比传统的 JavaScript (JS) 最大的优势在于静态类型检查代码提示更完善以及在开发阶段捕获潜在错误

1. 基础类型声明

TS 最基础的功能是给变量、函数参数和返回值添加类型约束。

JS 写法:

let count = 0; function add(a, b) { return a + b; }

TS 写法:

let count: number = 0; // 约束参数和返回值类型,防止传入字符串导致意外行为 function add(a: number, b: number): number { return a + b; }

2. 接口与类型别名

在处理小程序后端返回的数据或复杂对象时,定义结构至关重要。

JS 写法:

// JS 只能靠注释说明,没有约束 function getUser() { return { id: 1, name: '张三', age: 18 }; } let user = getUser(); console.log(user.nme); // 拼写错误,JS运行时才报错或静默失败

TS 写法:

// 定义接口 interface User { id: number; name: string; age?: number; // 可选属性(带问号) readonly createTime: string; // 只读属性 } function getUser(): User { return { id: 1, name: '张三', createTime: '2023-01-01' }; } let user = getUser(); console.log(user.nme); // 编译报错:Property 'nme' does not exist on type 'User'

3. 联合类型与字面量类型

小程序中常有状态值(如订单状态:1待付款,2已付款)或固定类型的参数。

JS 写法:

let status = 1; // 可能被误赋值为 '1' 或其他无关数字 function setTheme(theme) {} // theme是什么完全不知道

TS 写法:

// 联合类型 let status: number | string = 1; status = 'success'; // 允许 // 字面量联合类型(常用于状态机、枚举替代) type OrderStatus = 'unpaid' | 'paid' | 'shipped' | 'completed'; function setOrderStatus(status: OrderStatus) { // ... } setOrderStatus('paid'); // 正确 setOrderStatus('cancel'); // 编译报错

4. 泛型 - 封装网络请求

封装uni.request时,泛型是 TS 最强大的功能之一,能让你在不同的接口调用中获得不同的数据类型提示。

JS 写法:

// 封装 function request(url, data) { return new Promise((resolve, reject) => { uni.request({ url, data, success: res => resolve(res.data), fail: err => reject(err) }); }); } // 调用 const res = await request('/api/user', {}); console.log(res.name); // 没有提示,不知道res里有什么

TS 写法:

// 封装:使用泛型 T 表示返回的数据结构 function request<T = any>(url: string, data?: any): Promise<T> { return new Promise((resolve, reject) => { uni.request({ url, data, success: (res) => resolve(res.data as T), fail: (err) => reject(err) }); }); } // 定义接口数据类型 interface UserInfo { id: number; name: string; } // 调用:传入具体类型,res 自动推导为 UserInfo const res = await request<UserInfo>('/api/user', {}); console.log(res.name); // 有完美代码提示!

5. 枚举

用于管理项目中全局的常量(如 tabBar 的 pagePath、错误码等)。

JS 写法:

const Color = { RED: 'red', GREEN: 'green' }; console.log(Color.RED);

TS 写法:

enum Color { RED = 'red', GREEN = 'green', BLUE = 'blue' } console.log(Color.RED); // 代码提示更好,且防止使用未定义的枚举值

6. Vue 组件 Props 的类型定义

在 uni-app 中,Vue 3 的组件 Props 定义是高频场景。

JS 写法:

export default { props: { title: String, user: Object // 不知道user里面有什么字段 } }

TS 写法:

import { defineComponent, PropType } from 'vue'; interface UserProps { id: number; name: string; } export default defineComponent({ props: { title: { type: String, required: true }, // 使用 PropType 断言对象类型 user: { type: Object as PropType<UserProps>, required: true }, // 验证数组类型 list: { type: Array as PropType<string[]>, default: () => [] } }, setup(props) { console.log(props.user.name); // 完美提示 } })

7. Composition API 与 Ref 的类型

在 uni-app 的 Vue3 开发中,refreactive的类型定义。

JS 写法:

import { ref, reactive } from 'vue'; const count = ref(0); // 自动推断为数字 const user = ref(null); // 推断为 null,后续赋值对象无提示

TS 写法:

import { ref, reactive } from 'vue'; interface UserInfo { name: string; age: number; } // 1. ref 的泛型用法 const user = ref<UserInfo | null>(null); user.value = { name: '张三', age: 18 }; // 正确 user.value.age = 20; // 提示正常 // 2. reactive 直接有类型推导 const state = reactive({ list: [] as string[] // 在对象内部断言 });

9. 高级工具类型(Pick / 交叉类型)- 复杂表单参数的组装

在 uni-app 小程序开发中,经常遇到“编辑个人资料”表单。我们需要从完整的用户详情ProfileDetail中提取部分字段,再合并一些特有的省市编码字段用于提交给后端。此时Pick&(交叉类型)能大显身手。

Pick:它是 TypeScript 的内置工具类型。它的作用就像“挑水果”一样,从一个已有的类型中,精准挑选出你指定的几个属性,丢弃其他属性,从而生成一个新的子类型。

JS 写法:

// JS 无法复用已有对象结构,只能手写全部字段,极易遗漏或写错 /** * @typedef {Object} ProfileParams * @property {string} nickname - 昵称 * @property {string} gender - 性别 * @property {string} provinceCode - 省份编码 (可选) * ... */ function updateProfile(params) { console.log(params.nickname); }

TS 写法:

// 假设这是从后端获取的用户详情结构 interface ProfileDetail { id: string; nickname: string; gender: string; birthday: string; profession: string; // ... 其他几十个字段 } // 1. 使用 Pick 挑出需要编辑的字段,使用 & 补充提交时需要的额外字段 export type ProfileParams = Pick< ProfileDetail, 'nickname' | 'gender' | 'birthday' | 'profession' > & { /** 省份编码 */ provinceCode?: string /** 城市编码 */ cityCode?: string /** 区县编码 */ countyCode?: string } // 2. 提交函数约束 function updateProfile(params: ProfileParams) { console.log(params.nickname); // 完美提示 // console.log(params.id); // 编译报错!防止误传 id 给后端 } // 调用时严格校验字段 updateProfile({ nickname: '张三', gender: '男', birthday: '2000-01-01', profession: '码农', // cityCode: '110100' // 可选字段不传也不报错 });

优势:如果后端修改了ProfileDetail中的birthday字段名为birthDate,你的ProfileParams会立刻在编译阶段红线报错,彻底杜绝前后端字段对不上的隐患。

8. 类型断言 - 初始化空对象与类型转换

在页面初始渲染时,我们常定义一个空对象用来存放稍后从后端请求回来的数据。但在 TS 中,如果直接给ref赋空对象{},会报错提示缺少必填属性。此时使用as关键字进行类型断言,相当于告诉编译器:“我知道它是空对象,但你先按这个类型给我提示”。

JS 写法:

import { ref } from 'vue'; // JS 毫无提示,后续给 profile 赋值时打错字也不会报错 const profile = ref({});

TS 写法:

import { ref } from 'vue'; // 1. 定义详情接口 interface ProfileDetail { id: number; nickname: string; gender: string; } // 2. 使用 as 进行类型断言,初始化为空对象但拥有完整类型提示 const profile = ref<ProfileDetail>({} as ProfileDetail); // 3. 模板中使用 profile.nickname 会有代码提示 // 4. 异步获取数据后赋值 profile.value = { id: 1, nickname: '张三', gender: '男' }; // 注意:断言是双刃剑。如果用 as 强行断言错误类型,会骗过编译器: // let a = 'hello' as number; // 报错,TS不允许差异过大的断言 // let b = ({} as any) as number; // 滥用 any 断言会导致运行时错误,需谨慎

优势:完美解决了“声明时还没数据,用空对象初始化会报错”的尴尬,同时保证了后续业务代码拥有完美的类型推导和防错能力。

9. uni-app/微信小程序原生 API 的类型

uni-app 官方提供了完整的 d.ts 文件,所有的uni.xxxAPI 都有类型支持。

JS 写法:

uni.getSystemInfo({ success: function(res) { console.log(res.model); // 靠记忆或查文档才知道有model console.log(res.windowWidth); // 拼错完全没提示 } });

TS 写法:

uni.getSystemInfo({ success: (res) => { // res 自动推断为 UniApp.GetSystemInfoResult console.log(res.model); // 有提示 console.log(res.windowWidth); // 有提示 // console.log(res.windowHight); // 拼错会有红线报错 } });
http://www.jsqmd.com/news/1170252/

相关文章:

  • 禅道 22.x 缺陷管理实战:5步闭环流程与7种解决方案详解
  • 从廊坊到全国:君启修缮“全国连锁+廊坊总部”双优势如何构建标准化防水服务体系? - 鲁顺
  • 弱模型在多次生成调用PaddlePaddle失败的代码后
  • syscontainer-tools 与 iSulad 集成指南:构建企业级容器平台
  • 告别出差:AR远程运维如何让专家“瞬移”到设备现场
  • TPA3128D2与PIC18F4550打造高性价比D类功放方案
  • 数字生命体作为智能观察员:从角色定义到平台集成实践
  • CD4511 与 NE555 驱动数码管:从静态显示到过流闪烁的3种电路设计对比
  • CryptoJS 4.0.0 AES 前端加密实战:ECB与CBC模式3种代码实现对比
  • 2026珠海叉车出租网点硬核横评:六家实体商家实测数据与避坑选型终极指南 - 品牌报告
  • 本科毕业论文 AI 率 40% 怎么降到 20% 以内一次过?
  • MatrixCPP社区贡献指南:如何参与openEuler分布式编程规范开发
  • 【LLM系列】深入拆解投机解码:大模型推理提速3-5倍的核心技术,从原理到生产全解析
  • FPGA工程师的Copilot实战:Verilog与Vivado Tcl智能补全指南
  • 亨得利官方名表服务中心|网点地址与售后服务热线权威信息通告(2026年7月更新) - 亨得利官方博客
  • 一块好电木板能用十年,浙江亚格电子品质靠谱质量好,品牌推荐排名靠前厂家推荐首选 - 品牌速递
  • KMS智能激活工具:5分钟解决Windows和Office永久激活难题
  • etipc性能调优:提升Linux内核模块通信效率的完整指南
  • 终极REAPER脚本指南:500+免费脚本彻底改变你的音频工作流
  • 禅道 22.2 缺陷管理实战:从提交到关闭的 5 步标准化流程与 3 个关键字段
  • requirements.txt 进阶:3种指定GitHub仓库依赖的语法与实战避坑
  • 2026年7月最新常州美度官方售后服务网点地址及客服电话一览 - 亨得利钟表维修中心
  • 5分钟让你的Windows任务栏焕然一新:终极透明美化神器
  • 奢侈品稀缺度定价算法,根据限量数量计算单品合理溢价区间平衡销量与档次。
  • 中考出分择校热潮来袭!南昌理工技工学校咨询现场爆满,热门专业名额速抢 - 新闻快传
  • [ScleraLimbalRing节点]原理解析与实际应用
  • NestOS:openEuler社区孵化的云底座操作系统,如何成为容器主机最佳选择?
  • 5分钟快速上手:NewGAN-Manager足球经理头像配置终极指南 [特殊字符]
  • 浙江亚格电子电木板:客户至上服务理念践行,质量稳定获一致好评 - 品牌速递
  • 2026年7月最新无锡雅典官方售后联系电话与客户服务中心网点地址 - 亨得利官方服务中心