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

阮一峰《TypeScript 教程》学习笔记——运算符

1. 一段话总结

TypeScript 提供多种类型运算符,用于对已有类型进行计算生成新类型,核心包括keyof(提取对象键名组成联合类型)、in(遍历联合类型成员)、方括号运算符(提取对象键值类型)、extends…?:(条件判断类型,子类型则返回X否则Y)、infer(在条件类型中推断泛型参数)、is(描述函数返回值与参数的类型关系,实现类型保护)、模板字符串类型(引用特定类型构建新字符串类型);这些运算符需结合泛型、联合类型等使用,可实现属性映射、类型提取、条件分支等复杂类型逻辑。


2. 思维导图

在这里插入图片描述


3. 详细总结

一、keyof 运算符

核心维度说明示例代码
作用接受对象/类型作为参数,返回其所有键名组成的联合类型`type MyObj = {foo: number; bar: string}; type Keys = keyof MyObj; // ‘foo’
语法keyof 目标类型-
特殊场景处理1. 数组/元组:返回 `number索引字符串
核心用途1. 精确关联函数参数与返回值类型(如 function prop<O,K extends keyof O>(obj:O, key:K):O[K]);
2. 实现属性映射(如去除只读/可选属性)
type Mutable<O> = { -readonly [P in keyof O]: O[P] }; // 去除只读属性

二、in 运算符

核心维度说明示例代码
作用在TypeScript中用于遍历联合类型的每个成员,生成对象类型`type U=‘a’
语法[变量名 in 联合类型]: 目标类型-
与JavaScript差异
环境作用示例
JavaScript判断对象是否包含某属性(返回布尔值)'a' in {a:1} → true
TypeScript遍历联合类型成员,构建对象类型`type U=‘a’

三、方括号运算符

核心维度说明示例代码
作用提取对象指定键名的键值类型,支持联合键名type Person={age:number;name:string}; type Age=Person['age']; // number
语法目标类型[键名/键名联合类型]-
特殊场景1. 联合键名:返回对应键值的联合类型(如 `Person[‘age’‘name’] → number

四、extends…?: 条件运算符

核心维度说明示例代码
作用判断类型 T 是否为 U 的子类型,是则返回 X,否则返回 Ytype T=1 extends number ? true : false; // true
语法T extends U ? X : Y-
联合类型处理自动展开联合类型,每个成员单独判断后返回联合结果(`(AB)extends U → (A→X/Y)
避免展开TU 用方括号包裹([T] extends [U]),联合类型不展开`type ToArray=[T] extends [any] ? T[] : never; type T=ToArray<string
嵌套使用支持多重条件判断,实现复杂类型分支type LiteralTypeName<T>=T extends undefined?'undefined':T extends null?'null':never;

五、infer 关键字

核心维度说明示例代码
作用在条件类型中推断泛型参数(无需外部传入,从当前类型信息推导)type Flatten<T>=T extends Array<infer Item> ? Item : T;
语法T extends 父类型<infer 推断参数> ? 推断参数 : T-
适用场景1. 提取数组成员类型(如 Flatten<string[]> → string);
2. 提取函数参数/返回值(如 type Return<T>=T extends (...args:infer A)=>infer R ? R : T);
3. 提取对象属性类型(如 type ExtractProp<T>=T extends {a:infer M,b:infer N} ? [M,N] : never
type Func=(x:number)=>string; type FuncReturn=Return<Func>; // string

六、is 运算符

核心维度说明示例代码
作用描述函数返回值与参数的类型关系,实现类型保护(缩小变量类型范围)`function isFish(pet:Fish
语法函数返回值类型 → 参数名 is 目标类型-
适用场景1. 判断参数类型(如 if(isFish(x)) x.swim();,确保x为Fish类型);
2. 类方法返回值(用 this is T 描述当前实例类型)
class Student { isStudent():this is Student { return true; } }

七、模板字符串类型

核心维度说明示例代码
作用引用特定类型构建新字符串类型,支持展开联合类型type World="world"; type Greeting=hello ${World}; // "hello world"
语法`字符串片段${引用类型}字符串片段`-
引用限制仅支持引用 6种类型:string、number、bigint、boolean、null、undefined,其他类型(如对象)会报错type Obj={n:123}; type T=${Obj}; // 报错
联合类型展开引用多个联合类型时,会交叉展开生成所有组合(如 `T=‘A’‘B’; U=‘1’

4. 关键问题

问题1:TypeScript 中 keyofin 运算符的核心差异是什么?分别适用于哪些场景?

答案
两者核心差异体现在“作用对象”和“功能目标”,适用场景完全不同:

  1. 核心差异
    维度keyof 运算符in 运算符
    作用对象对象/类型(如接口、type别名)联合类型(如 `‘a’
    核心功能提取对象的键名,生成联合类型遍历联合类型成员,生成对象类型
    语法形式keyof 目标类型[变量名 in 联合类型]: 类型
  2. 适用场景
    • keyof:适用于“需要获取对象所有键名”的场景,如精确关联函数参数与返回值(如 function prop<O,K extends keyof O>(obj:O, key:K):O[K])、实现属性映射(如去除只读属性);
    • in:适用于“需要基于联合类型构建对象”的场景,如将联合类型成员转为对象属性(如 type U='a'|'b'; type Foo={ [P in U]: number })、批量生成属性类型。

问题2:extends…?: 条件运算符处理联合类型时会自动展开,如何理解这一行为?若需避免展开,有什么方法?请结合示例说明。

答案

  1. 自动展开行为
    extends…?: 的左侧类型为联合类型(如 A|B)时,TypeScript 会将联合类型“拆分为单个成员”,分别判断每个成员是否为右侧类型的子类型,最终将结果组合为新的联合类型,即:
    (A|B) extends U ? X : Y ≡ (A extends U ? X : Y) | (B extends U ? X : Y)
    示例:

    type ToArray<T> = T extends any ? T[] : never;
    type Result = ToArray<string|number>; // string[]|number[](联合类型展开)
    
  2. 避免展开的方法
    将条件运算符中 extends 两侧的类型用方括号包裹(如 [T] extends [U]),此时 TypeScript 会将联合类型视为“单个整体”,不进行拆分,示例:

    type ToArray<T> = [T] extends [any] ? T[] : never;
    type Result = ToArray<string|number>; // (string|number)[](未展开)
    
  3. 适用场景

    • 需“分别处理联合类型成员”时保留展开(如批量将每个成员转为数组);
    • 需“将联合类型作为整体”时避免展开(如将联合类型整体转为数组)。

问题3:infer 关键字的核心作用是什么?如何利用它提取函数的参数类型和返回值类型?请结合示例说明。

答案

  1. 核心作用
    infer 用于在 条件类型 中“自动推断泛型参数”,无需从外部传入,仅需从当前类型信息(如数组、函数、对象)中推导,简化复杂类型提取逻辑。

  2. 提取函数参数与返回值类型
    利用 infer 在条件类型中匹配函数类型,分别推断“参数列表类型”和“返回值类型”,语法为:
    type 类型别名<T> = T extends (...args: infer 参数类型) => infer 返回值类型 ? [参数类型, 返回值类型] : T
    示例:

    // 提取函数的参数类型和返回值类型
    type ExtractFunc<T> = T extends (...args: infer Args) => infer Return ? { args: Args; return: Return } : never;// 测试:函数 (x:number, y:string)=>boolean
    type Func = (x:number, y:string)=>boolean;
    type FuncInfo = ExtractFunc<Func>; 
    // 结果:{ args: [x:number, y:string]; return: boolean }
    
  3. 优势
    若不使用 infer,需手动传入参数类型和返回值类型(如 type ExtractFunc<T, Args, Return> = T extends (...args:Args)=>Return ? ... : ...),而 infer 可自动推导,减少冗余代码。

http://www.dtcms.com/a/532655.html

相关文章:

  • 协作协议(Collaborative Protocols)——下一代人机协作操作系统的工程化实践
  • I2C 驱动 --- 控制器
  • 创意网站设计团队郑州百度推广托管
  • 网盘做网站空间杭州简单网技术有限公司
  • TensorFlow学习入门
  • 强电控制器-非正常工作实验
  • 网站修改域名服务器企业静态网站
  • GitHub等平台形成的开源文化正在重塑结帖人
  • 考古并发历史(1)
  • 班级网站设计外国大气网站
  • 深拷贝浅拷贝
  • 样本与样本值
  • 无极网站网站首屏高度
  • ansible自动化运维入门篇-ansible部署
  • 如何在搜索中找到自己做的网站o2o电商交易类平台有哪些
  • Rust中错误处理机制
  • Ubuntu 24.04上安装MySQL 8.0
  • Java基于SpringBoot的高校报修与互助平台小程序【附源码、文档说明】
  • 工信部icp备案流程关键词在线优化
  • 做视频的模板下载网站ppt汇报模板免费下载
  • 10.16-10.25力扣计数刷题
  • 在K8s中部署多个ASP.NET Core实例
  • 14.如何利用ArcGIS将矢量线、面的坐标数据保存为txt
  • 网站开发者模式怎么打开做策划网站推广怎么写简历
  • zynq ttc pwm例子
  • 【底层机制】linux IO 为什么要有进程表项、文件表项、v节点表项、i节点表项
  • 怎么用wordpress修改网站源码镇江网站网站建设
  • 设计方案表网站名称汉台网站制作
  • git误合并两分支如何回退
  • 【Linux系统编程】编译器gcc/g++