TypeScript 一日速通指南:数据类型全解析与转换指南
TypeScript 数据类型全解析与转换指南
一、核心数据类型体系
1. 基础类型(Primitive Types)
| 类型 | 描述 | 示例 | 特殊说明 |
|---|---|---|---|
number | 数值类型(含整数、浮点数、科学计数法) | let age: number = 25; | 支持二进制(0b)、八进制(0o)、十六进制(0x)字面量 |
string | 字符串类型 | const str: string = "TypeScript"; | 支持模板字符串(`Hello ${name}`) |
boolean | 布尔值 | let flag: boolean = true; | 仅true/false两个值 |
symbol | 唯一标识符 | const sym: symbol = Symbol(); | 用于对象属性的唯一键 |
bigint | 任意精度整数 | const big: bigint = 123n; | 需添加ESNext到tsconfig.lib |
2. 复合类型(Compound Types)
| 类型 | 描述 | 示例 |
|---|---|---|
Array<T>/T[] | 数组类型 | const arr: number[] = ; |
Tuple | 固定长度和类型的数组 | let tuple: @ref; |
enum | 枚举类型(数字/字符串枚举) | enum Color { Red, Green } |
object | 非原始类型(排除number/string/boolean等) | const obj: object = { a: 1 }; |
any | 任意类型(慎用) | let data: any = apiResponse; |
unknown | 安全的未知类型(需类型守卫) | let input: unknown = getInput(); |
3. 特殊类型
| 类型 | 描述 | 示例 |
|---|---|---|
void | 无返回值函数 | function log(): void {} |
never | 永不存在值的类型(抛出异常/死循环) | function error(): never {} |
literal | 字面量类型(精确匹配特定值) | `type Status = “success” |
二、类型转换全攻略
1. 显式类型转换
1.1 类型断言(Type Assertion)
// 尖括号语法conststr:unknown="123";constnum:number=(<string>str).length;// as 语法(推荐)constarr:any@ref;constfiltered=arr.filter((item):itemisnumber=>typeofitem==="number");1.2 函数转换
// 字符串转数字constnumStr:string="123.45";constnum:number=Number(numStr);// 123.45constint:number=parseInt(numStr,10);// 123// 数字转字符串constnum:number=42;conststr1:string=String(num);// "42"conststr2:string=num.toString();// "42"2. 隐式类型转换
2.1 运算符驱动
// 字符串拼接constresult=5+"px";// "5px"(数字隐式转字符串)// 逻辑运算constisAdmin=true;constisAdminStr=isAdmin+"";// "true"(布尔值转字符串)// 算术运算constvalue="10"-5;// 5(字符串转数字)constisTruthy=!!value;// true(数字转布尔)2.2 类型收窄(Type Narrowing)
functionprintLength(value:unknown){if(typeofvalue==="string"){console.log(value.length);// 类型收窄为 string}elseif(Array.isArray(value)){console.log(value.length);// 类型收窄为 any[]}}三、避坑指南与最佳实践
1. 类型转换常见陷阱
| 问题类型 | 示例 | 修复方案 |
|---|---|---|
| 隐式转换导致的精度丢失 | const a: number = 0.1 + 0.2; | 使用toFixed()控制精度 |
| any 类型滥用 | let data: any = apiResponse; | 改用泛型 + 类型守卫 |
| null/undefined 处理 | const len = str.length; | 添加非空断言str!.length或默认值 |
| 枚举反向映射失效 | enum Color { Red = 1 } | 使用Color时需确保唯一性 |
2. 安全转换模式
// 安全解析 JSONconstparseJSON=<T>(json:string):T=>{try{returnJSON.parse(json);}catch{thrownewError("Invalid JSON");}};// 类型守卫组合constisUser=(obj:unknown):objisUser=>{return(typeofobj==="object"&&"id"inobj&&typeof(objasUser).id==="string");};3. 性能优化技巧
// 避免重复类型断言constprocess=(data:unknown)=>{conststr=dataasstring;// 单次断言returnstr.toUpperCase();};// 使用类型谓词减少重复检查typePrimitive=string|number|boolean;constisPrimitive=(val:unknown):valisPrimitive=>{returnval===null||typeofval!=="object";};四、进阶类型转换
1. 高级类型操作
// 映射类型转换typeReadonlyUser=Readonly<User>;// 条件类型过滤typeFilterString<T>=Textendsstring?T:never;// 模板字面量类型typeEvent="click"|"hover";typeHandler=`${Event}Handler`;2. 运行时类型校验
// Zod 校验库示例import{z}from"zod";constUserSchema=z.object({id:z.string().uuid(),age:z.number().int().positive(),});constparseUser=(input:unknown)=>{returnUserSchema.parse(input);};五、实战建议
- 类型优先原则:优先使用
unknown而非any,通过类型守卫逐步缩小范围 - 严格模式配置:
// tsconfig.json{"compilerOptions":{"strictNullChecks":true,"noImplicitAny":true,"strictFunctionTypes":true}} - 类型文档化:为复杂类型添加 JSDoc 注释
/** * @typedef {Object} User * @property {string} id - 用户唯一标识 * @property {"admin"|"user"} role - 用户角色 */
通过掌握类型系统的核心机制和转换技巧,开发者可以显著提升代码健壮性。建议结合具体业务场景,灵活运用类型断言、类型守卫和高级类型工具,构建类型安全的代码体系。
React/Vue/Angular项目中,类型转换有哪些特殊注意点
在 React/Vue/Angular 项目中使用 TypeScript 时,类型转换需特别注意框架特性与类型系统的交互。以下是各框架的核心注意事项及通用最佳实践:
一、React 项目注意事项
1.组件 Props 类型安全
- 问题:直接传递
any类型或未定义 Props 会导致运行时错误 - 解决方案:
// 使用泛型精确约束 interface User { id: string; name: string } const UserProfile = ({ user }: { user: User }) => { /* ... */ } // 使用 TypeScript 的泛型约束 const fetchUser = <T extends { id: string }>(id: T["id"]): Promise<T> => { /* ... */ }
2.事件处理类型
- 问题:未正确标注事件对象类型会导致属性访问错误
- 解决方案:
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); // 自动提示 preventDefault 方法 }
3.状态管理类型
- 问题:useReducer/useContext 的泛型缺失导致类型推断错误
- 解决方案:
type State = { count: number }; const [state, dispatch] = useReducer(reducer, initialState as State);
二、Vue 项目注意事项
1.响应式类型推导
- 问题:reactive/ref 的初始值类型推断不准确
- 解决方案:
// 显式标注类型constcount=ref<number>(0);constuser=reactive<{name:string}>({name:"John"});
2.组件 Props 与 Emits
- 问题:未使用 defineProps/defineEmits 导致类型丢失
- 解决方案:
// script setup 语法constprops=defineProps<{list:Array<{id:number}>;}>();constemit=defineEmits<{(e:"update",value:string):void;}>();
3.解构响应式对象
- 问题:解构导致响应性丢失
- 解决方案:
// 正确方式const{foo}=toRefs(state);// 错误方式(失去响应性)const{foo}=state;
三、Angular 项目注意事项
1.依赖注入类型
- 问题:未标注服务类型导致注入错误
- 解决方案:
@Injectable({providedIn:'root'})classDataService{getData():Observable<Data[]>{returnof([]asData[]);}}
2.RxJS 类型操作
- 问题:未正确标注 Observable 类型
- 解决方案:
getData():Observable<{id:string}[]>{returnthis.http.get<{id:string}[]>('/api/data');}
3.模板类型检查
- 问题:模板中访问未定义的属性
- 解决方案:
<!-- 使用安全导航操作符 --><div*ngIf="user?.address?.city"></div>
四、跨框架通用最佳实践
1.类型断言陷阱
- 问题:滥用
as导致运行时错误// 错误示例 const data = localStorage.getItem("key") as string; // 可能为 null - 解决方案:
constdata=localStorage.getItem("key");if(typeofdata==="string"){// 安全操作}
2.第三方库类型处理
- 问题:缺乏类型定义导致类型错误
- 解决方案:
// 声明文件补充declaremodule"legacy-lib"{exportfunctiongetData():Promise<{id:string}[]>;}
3.异步数据类型
- 问题:未处理 Promise 的泛型类型
- 解决方案:
constfetchData=async():Promise<User[]>=>{constres=awaitfetch("/api/users");returnres.json()asPromise<User[]>;// 需要运行时验证}
4.类型守卫实践
- 问题:未正确缩小联合类型范围
- 解决方案:
functionisUser(obj:unknown):objisUser{return"id"inobj&&typeofobj.id==="string";}
五、框架对比与特殊场景
| 场景 | React | Vue | Angular |
|---|---|---|---|
| DOM 操作类型 | 使用ref+ 类型断言 | 使用ref显式标注 | 使用@ViewChild类型参数 |
| 状态管理 | Redux Toolkit 的createSlice泛型 | Pinia 的defineStore类型推导 | NgRx 的Action类型标注 |
| 表单处理 | Formik 的FieldProps泛型 | Element Plus 的defineComponent | ReactiveFormsModule 类型检查 |
| 路由参数类型 | React Router 的useParams泛型 | Vue Router 的defineRoute | Angular Router 的路由守卫类型 |
六、调试与验证工具
类型校验库:
import{z}from"zod";constschema=z.object({id:z.string().uuid()});constdata=schema.parse(apiResponse);// 运行时验证类型可视化:
// 查看类型定义typeProps=typeofcomponent.props;严格模式配置:
// tsconfig.json{"compilerOptions":{"strictNullChecks":true,"noUncheckedIndexedAccess":true}}
通过遵循框架特性和类型系统规则,开发者可以在 React/Vue/Angular 项目中充分发挥 TypeScript 的优势,同时规避类型相关的潜在风险。建议结合具体业务场景,建立统一的类型规范和代码检查流程。
