news 2026/6/7 19:43:24

TypeScript学习-第3章:复合类型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TypeScript学习-第3章:复合类型

TypeScript学习-第3章:复合类型

各位前端工友们,上一章咱们搞定了基础类型,相当于摸清了TS世界里的“单个零件”——字符串、数字这些独立个体。但实际开发中,咱们面对的都是“组装件”:比如用户列表是多个用户对象组成的集合,一条订单信息里既有字符串姓名,又有数字金额。

这一章咱们就解锁“零件组装技能”——复合类型,核心搞定数组、元组、对象这三大主力,学会给复杂数据结构“贴精准标签”。如果说基础类型是“单兵作战”,那复合类型就是“团队协作”,掌握它们才能应对真实业务场景。

一、数组类型:同类元素的“整齐队列”

数组咱们在JS里天天用,本质是“一组相同类型的数据集合”。TS给数组加类型约束,就是给这个队列定规矩:“所有人必须是同一种身份”,避免混进“异类”。咱们先讲两种声明方式,再聊只读数组的特殊用法。

1. 两种声明方式:各有适配场景

TS里数组有两种标注风格,按需选择即可,核心效果一致:

  • 简洁式:type[]——日常开发首选,写法清爽。在基础类型后面加[],就表示“该类型的数组”。
    // 数字数组:只能存数字 let scores: number[] = [90, 85, 95]; // 字符串数组:只能存字符串 let names: string[] = ["张三", "李四", "王五"]; // 错误示例:混存不同类型会标红 // let mixArr: number[] = [10, "20"]; // 类型不匹配

  • 泛型式:Array<type>——基于泛型语法(后续章节会深入),适合复杂场景(如嵌套泛型)。写法是Array后跟尖括号,里面填元素类型。
    // 数字数组,和number[]等价 let scores: Array<number> = [90, 85, 95]; // 字符串数组,和string[]等价 let names: Array<string> = ["张三", "李四", "王五"];小提醒:日常开发用type[]就够了,只有当数组元素是泛型类型(比如后续的Array<Array<number>>二维数组)时,泛型式会更易读。

2. 只读数组:不能修改的“固定队列”

有些场景下,数组创建后就不能增删改元素(比如接口返回的固定列表),这时候就需要“只读数组”,相当于给队列上了“锁”,禁止任何修改操作。有两种声明方式:

  • readonly type[]——简洁式,在类型前加readonly
    // 只读字符串数组 let readonlyNames: readonly string[] = ["张三", "李四"]; // 以下操作都会报错:只读数组禁止修改 // readonlyNames.push("赵六"); // 禁止新增 // readonlyNames[0] = "张小三"; // 禁止修改元素 // readonlyNames.pop(); // 禁止删除

  • ReadonlyArray<type>——泛型式,和上面效果完全一致。
    let readonlyScores: ReadonlyArray<number> = [90, 85]; // 同样禁止所有修改操作 // readonlyScores[1] = 90; // 报错

避坑点:只读数组只是“禁止修改元素和长度”,如果元素是对象(引用类型),对象内部的属性仍可修改(后续对象部分会细说)。比如readonly {name: string}[],数组不能增删,但里面对象的name可以改。

二、元组(Tuple):固定“人数”和“身份”的队列

数组是“同类元素的可变长队列”,而元组是“固定长度、固定类型顺序的严格队列”——相当于规定了“队列里必须有n个人,第1个是A身份,第2个是B身份,不能多也不能少”。这种特性特别适合处理“结构固定的短数据”。

1. 元组的基础用法

声明语法:用[类型1, 类型2, ...]列出每个位置的类型,赋值时必须严格对应——长度一致、类型顺序一致。

// 元组:第1个元素是字符串(姓名),第2个是数字(年龄),第3个是布尔(是否成年)letperson:[string,number,boolean]=["张三",25,true];// 正确访问:按索引取对应类型的值letname:string=person[0];letage:number=person[1];// 错误示例:类型不匹配或长度不一致// let wrongPerson1: [string, number, boolean] = ["李四", "26", true]; // 第2个类型错误// let wrongPerson2: [string, number, boolean] = ["李四", 26]; // 长度不足

2. 元组的避坑点与实用场景

元组看似简单,但有两个容易踩的坑,还有几个高频实用场景,咱们逐一梳理:

  1. 越界赋值的隐患:虽然元组长度固定,但在非严格模式下,用push方法新增元素不会报错(严格模式下会警告),但新增元素的类型会被约束为元组所有类型的联合类型。
    let person: [string, number] = ["张三", 25]; person.push(30); // 非严格模式下不报错,新增元素必须是string或number // person.push(true); // 报错:布尔值不属于元组类型的联合类型建议:用元组就尽量保持“固定长度”,避免手动增删元素,开启严格模式可减少此类隐患。

  2. 可选元素(TS 4.0+支持):元组也可以有可选元素,用?标记,可选元素必须放在最后。
    // 第3个元素(手机号)是可选的 let user: [string, number, string?] = ["张三", 25]; user = ["李四", 26, "13800138000"]; // 也可以补全可选元素

  3. 实用场景:元组适合处理“结构固定的短数据”,比如接口返回的坐标([x, y])、用户的账号密码组合、函数返回的多值结果等。
    // 场景1:坐标(x是数字,y是数字) let position: [number, number] = [100, 200]; // 场景2:函数返回多值(成功状态+数据) function getUser(): [boolean, {name: string, age: number}] { return [true, {name: "张三", age: 25}]; }

三、对象类型:多类型元素的“组合体”

对象是TS里最常用的复合类型,本质是“键值对的集合”,每个键对应一个值,值可以是任意类型(基础类型、复合类型都可)。TS给对象加类型约束,就是给每个“键”指定对应的“值类型”,避免乱赋值。

1. 直接声明:快速约束简单对象

对于结构简单的对象,可直接在变量后标注类型,格式为{ 键1: 类型1; 键2: 类型2; ... },多个键值对用分号分隔(逗号也可,习惯用分号更规范)。

// 声明一个用户对象类型:name是字符串,age是数字,isAdult是布尔letuser:{name:string;age:number;isAdult:boolean;}={name:"张三",age:25,isAdult:true};

2. 可选属性:允许“可有可无”的键

实际开发中,有些对象属性不是必填的(比如用户的手机号、邮箱),这时候用?标记为可选属性——赋值时可以省略该属性,也可以补全。

// 手机号(phone)是可选属性letuser:{name:string;age:number;phone?:string;// 可选属性}={name:"张三",age:25// 省略phone属性,不报错};// 也可以补全可选属性user.phone="13800138000";

避坑点:访问可选属性时,TS会提示“可能为undefined”,需要先判断是否存在再使用,避免运行时错误。

// 正确写法:先判断phone是否存在if(user.phone){console.log(user.phone.length);// 不报错}

3. 只读属性:初始化后不能修改的键

有些对象属性初始化后就不能修改(比如用户的ID、订单编号),用readonly标记为只读属性——只能在创建对象时赋值,后续无法修改。

letuser:{readonlyid:number;// 只读属性name:string;}={id:1001,name:"张三"};user.name="张小三";// 可修改// user.id = 1002; // 报错:只读属性不能修改

和只读数组类似:只读属性只是“禁止修改属性值”,如果属性值是对象(引用类型),对象内部的属性仍可修改。

四、实践:复合类型的嵌套玩法

真实业务场景中,复合类型很少单独使用,大多是“嵌套组合”——比如对象数组、元组嵌套对象、对象里包含数组等。咱们结合两个高频场景,实战演练如何标注类型。

场景1:对象数组(最常用)

比如接口返回的用户列表,是“多个用户对象组成的数组”,标注时要先定义单个用户的对象类型,再用数组类型包裹。

// 单个用户的对象类型typeUser={id:number;name:string;age:number;phone?:string;};// 用户列表:User类型的数组letuserList:User[]=[{id:1001,name:"张三",age:25},{id:1002,name:"李四",age:26,phone:"13800138000"},{id:1003,name:"王五",age:24}];// 访问嵌套属性:类型安全有提示console.log(userList[0].name);// 张三(TS自动提示name属性)

场景2:元组嵌套对象

比如处理“用户信息+订单列表”的组合数据,元组第一个元素是用户对象,第二个元素是订单对象数组。

// 订单对象类型typeOrder={orderId:string;amount:number;};// 元组:第1个元素是User对象,第2个是Order数组letuserWithOrders:[User,Order[]]=[{id:1001,name:"张三",age:25},[{orderId:"OD2024001",amount:99},{orderId:"OD2024002",amount:199}]];// 访问嵌套数据console.log(userWithOrders[0].name);// 张三console.log(userWithOrders[1][0].amount);// 99

场景3:对象嵌套数组+可选属性

比如商品信息,包含基础属性和可选的规格数组。

typeProduct={id:number;name:string;price:number;specs?:string[];// 可选的规格数组};letproduct:Product={id:2001,name:"T恤",price:99,specs:["M码","L码","XL码"]};// 可选数组的安全访问if(product.specs){console.log(product.specs.length);// 3}

五、本章小结:复合类型的核心是“结构化约束”

这一章咱们吃透了数组、元组、对象三大复合类型,核心逻辑可以总结为:复合类型是基础类型的“结构化组合”,类型标注的本质是给“组合规则”贴标签——数组定“同类元素的队列规则”,元组定“固定长度和顺序的队列规则”,对象定“键值对的对应规则”。

新手容易踩的坑:一是混淆数组和元组的使用场景(变长用数组,定长用元组);二是忽略可选属性的undefined判断;三是误以为只读复合类型“内部属性也不可修改”。这些都需要通过实践慢慢磨合。

下一章咱们要升级技能,学习函数类型的精准约束——给函数的参数、返回值贴标签,让函数调用更安全、重构更放心。记得多动手写嵌套场景的代码,培养“结构化类型思维”,咱们下一章见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 6:05:46

十年攻防迭代:OWASP Top 10从代码漏洞到云原生供应链的安全范式革命

OWASP Top 10作为全球应用安全领域的“风向标”&#xff0c;其2013-2023十年间的版本迭代&#xff0c;不仅是应用安全风险清单的更新&#xff0c;更是数字技术生态演进下&#xff0c;网络攻防博弈从单点代码防御向全链路生态治理的深度变革。从SQL注入、XSS等传统应用层漏洞占据…

作者头像 李华
网站建设 2026/6/3 6:23:43

云原生测试工具演进方向预测

云原生测试的现状与挑战 随着云原生技术的普及&#xff0c;测试工具正面临容器化、微服务化和动态环境带来的新挑战。传统工具在Kubernetes等平台中常出现适配不足的问题&#xff0c;如环境部署效率低、监控可视化弱等。测试从业者需应对快速迭代的DevOps流程&#xff0c;这要…

作者头像 李华
网站建设 2026/5/29 18:37:13

AI教材写作必备!高效工具助力,产出低查重优质教材!

在编写教材的过程中&#xff0c;我总是能精准踩到“慢节奏”的各种雷点。即使框架和资料都有了&#xff0c;却常常被内容创作所困扰——一段话反复推敲半小时&#xff0c;仍觉得表达不够准确&#xff1b;章节之间的连接总是难以找到合适的词汇&#xff0c;导致创作频频暂停。更…

作者头像 李华
网站建设 2026/6/1 6:50:58

KIHU 快狐|65 寸横屏落地广告机 车站候车厅商业展示

在当今数字化时代&#xff0c;车站候车厅作为人流量密集的公共场所&#xff0c;成为了商业展示的重要场所。[KIHU快狐]推出的65寸横屏落地广告机&#xff0c;凭借其卓越的技术实力和多样化的应用场景&#xff0c;为车站候车厅带来了全新的商业展示解决方案。产品特点与技术优势…

作者头像 李华
网站建设 2026/5/31 17:28:08

计算机毕设Java基于web的园区车辆出入管理系统 基于Java Web的园区车辆智能出入管理解决方案 Java Web技术驱动的园区车辆通行管理系统设计与实现

计算机毕设Java基于web的园区车辆出入管理系统7iz8s9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 随着城市化进程的加速&#xff0c;园区的车辆管理成为了一个亟待解决的问题…

作者头像 李华