02. 基本类型 02. 基本类型1. 概述TypeScript 的核心特性是静态类型系统。基本类型是 TypeScript 类型系统的基础包括 JavaScript 原有的原始类型和 TypeScript 新增的特殊类型。// TypeScript 类型系统概览┌─────────────────────────────────────────────────────────────┐ │ TypeScript 类型系统 │ ├─────────────────────────────────────────────────────────────┤ │原始类型(Primitive Types)│ │ ├──string-字符串 │ │ ├──number-数字整数、浮点数、NaN、Infinity │ │ ├──boolean-布尔值 │ │ ├──null-空值 │ │ ├──undefined-未定义 │ │ ├──symbol-唯一值ES6 │ │ └── bigint-大整数ES2020 │ │ │ │ 特殊类型 │ │ ├──any-任意类型关闭类型检查 │ │ ├──unknown-未知类型类型安全的any │ │ ├──void-无返回值 │ │ ├──never-永远不会发生的类型 │ │ └── object-非原始类型 │ │ │ │ 复合类型 │ │ ├── array-数组 │ │ ├── tuple-元组 │ │ └──enum-枚举 │ └─────────────────────────────────────────────────────────────┘2. 原始类型2.1 string字符串// 字符串类型letname:stringTypeScript;letgreeting:stringHello, World!;lettemplate:stringHello,${name}!;// 模板字符串// 类型推断letmessageHello;// 自动推断为 string 类型// message 123; // ❌ 错误不能将 number 赋值给 string2.2 number数字// 数字类型整数、浮点数、十六进制、二进制、八进制letinteger:number42;letfloat:number3.14;lethex:number0xff;// 十六进制 (255)letbinary:number0b1010;// 二进制 (10)letoctal:number0o744;// 八进制 (484)letinfinity:numberInfinity;letnan:numberNaN;// 类型推断letcount100;// 自动推断为 number// count 100; // ❌ 错误2.3 boolean布尔值// 布尔类型letisDone:booleanfalse;letisEnabled:booleantrue;// 类型推断letisLoadingfalse;// 自动推断为 boolean// isLoading true; // ❌ 错误2.4 null 和 undefined// null 和 undefined 是所有类型的子类型strict 模式下除外letu:undefinedundefined;letn:nullnull;// 严格模式下null/undefined 只能赋值给自身或 anyletname:stringTypeScript;// name null; // ❌ 严格模式下错误// 联合类型可以包含 null/undefinedletmaybeName:string|nullTypeScript;maybeNamenull;// ✅ 允许2.5 symbol唯一值// Symbol 类型用于创建唯一标识符letsym1:symbolSymbol(key);letsym2:symbolSymbol(key);console.log(sym1sym2);// false每个 Symbol 都是唯一的// 作为对象属性键constKEYSymbol();constobj{[KEY]:value};2.6 bigint大整数// bigint 用于表示任意精度的整数ES2020letbigNumber:bigint9007199254740991n;letanother:bigintBigInt(9007199254740991);// 注意bigint 和 number 不能混用letnum:number100;// let result num bigNumber; // ❌ 错误类型不匹配3. 复合类型3.1 array数组// 两种定义方式letnumbers:number[][1,2,3,4,5];letstrings:Arraystring[a,b,c];// 混合类型数组使用联合类型letmixed:(number|string)[][1,two,3,four];// 只读数组letreadOnly:readonlynumber[][1,2,3];// readOnly[0] 10; // ❌ 错误只读数组不能修改// 类型推断letfruits[apple,banana];// 自动推断为 string[]3.2 tuple元组元组是固定长度和固定类型的数组。// 定义元组固定长度、固定类型顺序letperson:[string,number][Alice,25];// 访问元素letname:stringperson[0];// Aliceletage:numberperson[1];// 25// 元组越界访问TypeScript 会阻止// let extra person[2]; // ❌ 错误索引 2 超出长度// 可选元素letoptionalTuple:[string,number?][Alice];optionalTuple[Bob,30];// 也可以有两个元素// 剩余元素可变长度typeStringNumberBooleans[string,number,...boolean[]];lettuple:StringNumberBooleans[hello,42,true,false];3.3 enum枚举枚举用于定义一组命名的常量。// 数字枚举默认从 0 开始enumDirection{Up,// 0Down,// 1Left,// 2Right// 3}letdir:DirectionDirection.Up;console.log(dir);// 0// 自定义起始值enumStatus{Pending1,Approved2,Rejected3}// 字符串枚举enumColor{RedRED,GreenGREEN,BlueBLUE}// 异构枚举混合数字和字符串不推荐enumMixed{No0,YesYES}// 常量枚举编译时内联性能更好constenumLogLevel{ErrorERROR,WarnWARN,InfoINFO}// 编译后直接替换为值4. 特殊类型4.1 any任意类型any关闭类型检查可以赋任何值。letflexible:any42;flexiblestring;// ✅ 允许flexibletrue;// ✅ 允许flexible{key:value};// ✅ 允许flexible.unknownMethod();// ✅ 运行时才报错// 使用 any 会失去类型安全应尽量避免// 适用场景// 1. 迁移 JavaScript 代码时// 2. 处理动态内容// 3. 第三方库没有类型定义4.2 unknown未知类型unknown是类型安全的any必须先进行类型检查才能使用。letuserInput:unknownhello;// 不能直接使用// userInput.toUpperCase(); // ❌ 错误unknown 不能直接调用方法// 需要先进行类型收窄if(typeofuserInputstring){console.log(userInput.toUpperCase());// ✅ 安全}// 类型断言letstruserInputasstring;// 使用类型守卫functionisString(value:unknown):valueisstring{returntypeofvaluestring;}if(isString(userInput)){console.log(userInput.toUpperCase());}4.3 void无返回值// void 表示函数没有返回值functionlogMessage(message:string):void{console.log(message);// 没有 return 或 return undefined}// 变量可以赋值为 undefined 或 null非严格模式下letunusable:voidundefined;4.4 never永不返回never表示永远不会发生的类型。// 抛出错误的函数functionthrowError(message:string):never{thrownewError(message);}// 无限循环的函数functioninfiniteLoop():never{while(true){// 永远不会结束}}// 详尽性检查functionassertNever(x:never):never{thrownewError(Unexpected value: x);}// 在联合类型中使用typeShapecircle|square;functiongetArea(shape:Shape){switch(shape){casecircle:returnMath.PI*1;casesquare:return1*1;default:returnassertNever(shape);// 如果 shape 类型被扩展这里会报错}}4.5 object对象类型// object 表示非原始类型letobj:object{name:TypeScript};obj[1,2,3];// ✅ 数组也是对象obj(){};// ✅ 函数也是对象// 不能是原始类型// obj string; // ❌ 错误// obj 123; // ❌ 错误// 更精确的对象类型letperson:{name:string;age:number}{name:Alice,age:25};5. 类型推断TypeScript 能自动推断变量类型无需显式标注。// 变量类型推断letmessageHello;// 推断为 stringletcount42;// 推断为 numberletisValidtrue;// 推断为 boolean// 函数返回值推断functionadd(a:number,b:number){returnab;// 推断返回类型为 number}// 最佳通用类型letarr[1,string,true];// 推断为 (number | string | boolean)[]// 上下文类型推断window.onmousedownfunction(mouseEvent){console.log(mouseEvent.button);// mouseEvent 自动推断为 MouseEvent};6. 完整示例// 综合示例用户管理系统// 枚举定义用户角色enumUserRole{AdminADMIN,UserUSER,GuestGUEST}// 用户类型定义interfaceUser{id:number;name:string;email:string;role:UserRole;isActive:boolean;createdAt:Date;}// 函数创建用户functioncreateUser(name:string,email:string,role:UserRoleUserRole.User):User{return{id:Date.now(),name,email,role,isActive:true,createdAt:newDate()};}// 函数更新用户状态functionupdateUserStatus(user:User,isActive:boolean):User{return{...user,isActive};}// 函数获取用户信息可能不存在functiongetUserById(id:number):User|null{// 模拟查找if(id1){returncreateUser(Alice,aliceexample.com);}returnnull;}// 使用示例constnewUsercreateUser(Bob,bobexample.com,UserRole.Admin);console.log(newUser);constupdatedUserupdateUserStatus(newUser,false);console.log(updatedUser);constfoundUsergetUserById(1);if(foundUser){console.log(Found:${foundUser.name});}else{console.log(User not found);}7. 类型速查表类型语法示例值字符串stringhello数字number42,3.14布尔booleantrue,false数组type[]或Arraytype[1, 2, 3]元组[type1, type2][Alice, 25]枚举enum Name { A, B }Name.A任意any任何值未知unknown任何值需检查空voidundefined永不never无空值nullnull未定义undefinedundefined对象object{}SymbolsymbolSymbol()大整数bigint9007199254740991n8. 总结要点说明原始类型string、number、boolean、null、undefined、symbol、bigint复合类型array、tuple、enum特殊类型any、unknown、void、never、object类型推断TypeScript 自动推断变量类型最佳实践优先使用unknown而非any