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

TypeScript类型体操高级类型编程全攻略

TypeScript类型体操:高级类型编程全攻略

从基础泛型到复杂类型推导,掌握TypeScript类型系统的精髓


前言

TypeScript的类型系统是图灵完备的——这意味着你可以在类型层面进行任意复杂的计算。很多开发者对TypeScript的理解停留在interfacetype的基础用法,遇到复杂的类型场景就束手无策。

本文将从基础到进阶,系统讲解TypeScript的高级类型编程技巧,包括条件类型、映射类型、模板字面量类型、递归类型等,配合大量实战案例,帮你从"会写类型"进阶到"玩转类型"。


一、类型系统基础回顾

1.1 基础类型

// 原始类型letstr:string="hello";letnum:number=42;letbool:boolean=true;letnul:null=null;letundef:undefined=undefined;letsym:symbol=Symbol("key");letbig:bigint=100n;// 特殊类型letany:any="anything";// 任意类型,关闭类型检查letunknown:unknown="unknown";// 安全的any,使用前必须类型检查letnever:never;// 永远不会有值的类型letvoid_:void;// 函数无返回值// 数组letarr:number[]=[1,2,3];letarr2:Array<number>=[1,2,3];// 元组lettuple:[string,number]=["hello",42];

1.2 联合类型与交叉类型

// 联合类型:A | B(取并集,可以是A或B)typeStringOrNumber=string|number;letval:StringOrNumber="hello";// OKval=42;// OK// val = true; // Error// 交叉类型:A & B(取交集,同时是A和B)typeNamed={name:string};typeAged={age:number};typePerson=Named&Aged;letperson:Person={name:"Alice",age:30};// OK// let person2: Person = { name: "Bob" }; // Error: 缺少age属性// 联合类型的类型收窄functionprocess(value:string|number){if(typeofvalue==="string"){// 这里value被收窄为string类型console.log(value.toUpperCase());}else{// 这里value被收窄为number类型console.log(value.toFixed(2));}}

1.3 泛型基础

// 泛型函数functionidentity<T>(arg:T):T{returnarg;}// 泛型约束functiongetProperty<T,KextendskeyofT>(obj:T,key:K):T[K]{returnobj[key];}// 泛型接口interfaceRepository<T>{findById(id:string):Promise<T|null>;findAll():Promise<T[]>;save(entity:T):Promise<T>;delete(id:string):Promise<void>;}// 泛型类classStack<T>{privateitems:T[]=[];push(item:T):void{this.items.push(item);}pop():T|undefined{returnthis.items.pop();}}

二、条件类型(Conditional Types)

2.1 基本语法

// 语法:T extends U ? X : Y// 如果T是U的子类型,则为X,否则为YtypeIsString<T>=Textendsstring?true:false;typeA=IsString<string>;// truetypeB=IsString<number>;// falsetypeC=IsString<"hello">;// true(字面量类型是string的子类型)

2.2 infer关键字

infer用于在条件类型中推断(提取)类型:

// 提取函数返回类型typeReturnType<T>=Textends(...args:any[])=>inferR?R:never;typeR1=ReturnType<()=>string>;// stringtypeR2=ReturnType<(x:number)=>boolean>;// boolean// 提取函数参数类型typeParameters<T>=Textends(...args:inferP)=>any?P:never;typeP1=Parameters<(a:string,b:number)=>void>;// [a: string, b: number]// 提取Promise的值类型typeAwaited<T>=TextendsPromise<inferU>?Awaited<U>:T;typeA1=Awaited<Promise<string>>;// stringtypeA2=Awaited<Promise<Promise<number>>>;// number(递归提取)// 提取数组元素类型typeElementType<T>=Textends(inferE)[]?E:never;typeE1=ElementType<string[]>;// stringtypeE2=ElementType<number[]>;// number

2.3 分布式条件类型

当条件类型作用于联合类型时,会自动分布(distribute)到每个成员:

// 分布式条件类型typeToArray<T>=Textendsany?T[]:never;typeR=ToArray<string|number>;// 等价于:// ToArray<string> | ToArray<number>// = string[] | number[]// 不是 (string | number)[]// 阻止分布式行为typeToArrayNonDist<T>=[T]extends[any]?T[]:never;typeR2=ToArrayNonDist<string|number>;// = (string | number)[]

2.4 实战:Extract与Exclude

// Extract:从联合类型中提取满足条件的类型typeExtract<T,U>=TextendsU?T:never;typeE=Extract<string|number|boolean,string|boolean>;// = string | boolean// Exclude:从联合类型中排除满足条件的类型typeExclude<T,U>=TextendsU?never:T;typeE2=Exclude<string|number|boolean,string|boolean>;// = number// 实际应用:过滤函数类型typeNonFunction<T>=TextendsFunction?never:T;typeObj={name:string;age:number;greet:()=>void;calculate:(x:number)=>number;};typeDataOnly={[KinkeyofObjasObj[K]extendsFunction?never:K]:Obj[K];};// = { name: string; age: number }

三、映射类型(Mapped Types)

<

http://www.jsqmd.com/news/805200/

相关文章:

  • 告别U盘!手把手教你用Samba在Ubuntu 22.04上搭个‘网盘’,Windows访问超丝滑
  • 【AI】价值投资:从核心原理到进阶实践
  • Ubuntu 20.04下D435i/T265识别失败?别急着重装系统,先检查这个udev规则冲突
  • 如何快速下载抖音无水印视频:终极完整指南
  • 为什么你的“葛饰北斋”总像AI画的?揭秘浮世绘三大视觉铁律(轮廓线强度/平涂色域/浮雕感层次)在MJ中的像素级映射公式
  • idea不同仓库代码合并操作
  • 俄罗斯诚实标签采集技术解析及兴通物联设备选型指南
  • 厚街包装设计哪家值得推荐:秒杀包装设计专业靠谱 - 17322238651
  • 厚街礼仪模特哪家值得推荐:秒杀礼仪模特拔尖 - 13724980961
  • 厚街品牌策划哪家值得推荐:秒杀品牌策划口碑绝佳 - 13425704091
  • 10-workflow-multi-agent 多 Agent 工作流:复杂任务如何拆解和编排
  • 用PyTorch从零实现BERT:手把手教你构建自己的对话理解模型(附完整代码)
  • 一套搞定Spring循环依赖/事务/生命周期/传播特性/IOC/AOP/设计模式/源码!
  • 系统之家u盘装机大师
  • VR大空间:沉浸式数字体验引领新时代科普与教育升级
  • 终极虚拟机检测指南:5种方法精准识别虚拟环境
  • 让你的10美元鼠标超越苹果触控板:Mac Mouse Fix完全指南
  • 厚街电梯维保哪家值得推荐:秒杀电梯维保优质 - 19120507004
  • Spring Boot + Claude实时推理服务性能压测报告(QPS 1,842 vs 内存占用下降63%,附JVM调优参数清单)
  • 网站克隆工具大全
  • OpenClaw自托管AI助手平台:架构、安全与四大部署场景实战
  • 避坑指南:你的VASP Bader电荷分析为啥总报错?从LAECHG设置到NGXFYF参数详解
  • AI模型热更新引发服务雪崩?SITS 2026弹性拆分协议(v2.3.1草案)首次深度解读
  • 厚街中央空调维保哪家值得推荐:秒杀中央空调维保甄选首选 - 13724980961
  • redis-cli 客户端查询set集合里面的具体数据
  • Java面试难度骤升,普通程序员如何破局?
  • 线激光扫描精度上不去?可能是这5个标定步骤没做好(附OpenCV避坑指南)
  • 中小企业 AI 超级员工选型推荐
  • 20260512_200251_向量库是RAG的前菜,知识图谱是答案,本体论是灵魂
  • 《图书管理系统》用户管理模块UML实战:从用例图到时序图的StartUML高效绘制