
文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载导读从值获取类型Type from Value是 TypeScript 类型系统的基石能力你不需要为每个变量手写类型注解编译器会通过类型推断type inference自动从值或表达式推导出对应类型。本文将围绕 《The Concise TypeScript Book》的 值から型を取得する 章节 展开结合本书姊妹章节与完整源码系统讲解字面量推断、类型加宽、函数返回值推断、模块导出推断以及typeof操作符在类型层面的高级应用帮助你彻底理解并熟练运用从值获得类型这一日常开发中最频繁触发的类型机制。一、什么是从值获取类型Type from Value在 TypeScript 中Type from Value 指的是通过类型推断从某个值或表达式中自动推导出它的类型整个过程无需开发者显式写出类型注解。这是 TypeScript 区别于 Java、C# 等传统静态类型语言的重要特性之一编译器看着你的值就能告诉你它的类型是什么。本书 日文版原章节 给出的核心示例是一个字符串字面量const x x; // TypeScript 将 x 推断为字符串字面量类型因为 const 不可变 // 但若使用 let 声明则会把类型加宽widen为 string因为可重新赋值这段代码揭示了 TypeScript 类型推断的第一个关键规则——推断结果取决于变量的可变性const x xx永远无法被重新赋值因此 TypeScript 可以安全地把它的类型收窄为字面量类型xlet y xy随时可能被赋予其他字符串因此 TypeScript 会把类型加宽为string。在 《探索类型系统》章节 中本书进一步明确类型推断发生在变量初始化、成员初始化、参数默认值设置以及函数返回值这四类场景中编译器分析值或表达式后基于已有信息确定其类型let x x; // 推断出的类型是 string为什么这个能力重要它让 TypeScript 既具备静态类型检查的安全性又保持了类似 JavaScript 的书写流畅度。绝大多数业务代码中的变量、函数、对象都不需要手写注解类型系统会自动补全——这也是从值获取类型在实际工程中的最大价值。二、字面量推断与类型加宽const 与 let 的核心差异2.1 字面量推断的基本规则本书在 《字面量推断》章节 中给出了最直观的对比const x x; // 字面量类型 x因为这个值无法再改变 let y y; // string 类型因为我们可以随时改变这个值这条规则的本质是类型加宽type wideningTypeScript 在推断时会考虑变量未来的可赋值性。let声明的变量是可变的所以编译器保守地给出更宽的类型const声明的变量不可变所以编译器可以给出最精确的字面量类型。2.2 对象属性中的加宽问题字面量推断在对象属性上有一个容易踩坑的行为。当对象的属性值来自字面量时TypeScript 会认为该属性以后可能被修改从而将其推断为加宽后的类型而非字面量类型。本书给出了一个会产生编译错误的典型案例type X a | b; let o { x: a, // 这是一个被加宽为 string 的值 }; const fn (x: X) ${x}-foo; console.log(fn(o.x)); // Error: Argument of type string is not assignable to parameter of type X可以看到X是a | b这样更窄的联合类型而o.x被推断成了宽泛的string因此把o.x传给fn会触发类型错误。2.3 解决方案as const与类型断言本书给出了两种修复方式。第一种是使用const断言强制把属性收窄为字面量类型let o { x: a as const, };第二种是显式的类型断言把它断言到更具体的联合类型成员let o { x: a as X, };这两种写法分别对应 TypeScript 的精确字面量与收窄到特定类型两种诉求是解决对象属性加宽问题的标准手段。2.4 深入类型加宽与 const 的底层行为在 《探索类型系统》章节 中本书补充了更完整的加宽规则类型加宽是从窄到宽的单向过程——允许把窄类型赋给宽类型但不允许反向赋值let x x; // TypeScript 推断为 string宽类型 let y: y | x y; // y 是字面量类型的联合 y x; // Invalid类型 string 不能赋值给类型 x | y而使用const声明后类型被收窄为字面量类型反向赋值就合法了const x x; // TypeScript 将 x 的类型推断为 x更窄的类型 let y: y | x y; y x; // Validx 的类型被推断为 x为什么 const 能推断出字面量类型因为const变量不可重新赋值编译器有充分依据把类型锁定到具体的字面量x从而允许它在类型检查中精确参与后续判断。三、从函数返回值获取类型从值获取类型的第二个重要场景是函数返回值推断。本书在 《函数返回值的类型》章节 中说明TypeScript 会根据函数实现自动推断返回值类型无需显式类型注解。const add (x: number, y: number) x y; // TypeScript 可以推断出函数返回值类型是 number这里add的两个参数都有显式注解number而返回值类型number完全由编译器从x y这个表达式推断得出。这种推断能力在真实项目中意味着你不必为每个函数编写: ReturnType注解重构时返回类型也会自动跟随实现变化复杂表达式如数组操作链、Promise 链的最终返回类型同样会被精确推断结合泛型时推断会随类型参数的具体化而展开。本书在 《探索类型系统》章节 中明确列出了函数返回值的类型是 TypeScript 在无注解情况下自动推断的四大场景之一与变量初始化、成员初始化、参数默认值并列。四、从模块导出获取类型从值获取类型的第三个场景是跨模块的类型传递。本书在 《模块的类型》章节 中说明当模块导出一个具有特定类型的值时TypeScript 会利用该信息在另一个模块导入这个值时自动推断其类型。// calc.ts export const add (x: number, y: number) x y; // index.ts import { add } from calc; const r add(1, 2); // r 是 number 类型这段代码展示了从值到类型信息流的完整链条calc.ts中add函数被推断出返回number通过export导出时函数及其类型信息一起被打包进模块的类型声明index.ts中import { add }导入后TypeScript 依据模块的类型信息推断出调用结果r的类型为number。这是大型项目类型安全的关键机制只要每个模块的导出值类型准确下游所有 import 处的推断都能自动成立形成一条无需手动维护的类型链路。五、推断的机制最佳公共类型与上下文类型当类型推断涉及多个表达式时编译器会做更复杂的推导。本书在 《探索类型系统》章节 中讲解了两种高级推断行为。5.1 最佳公共类型Best Common Type当推断涉及多个值时TypeScript 会寻找所有候选类型的最佳公共类型let x [1, x, 1, null]; // 推断出的类型是 (string | number | null)[]当编译器找不到公共类型时则退回为联合类型let x [new RegExp(x), new Date()]; // 推断出的类型是 (RegExp | Date)[]5.2 上下文类型Contextual Typing除了从值本身推断TypeScript 还会依据变量/参数所处位置进行上下文类型化。例如lib.d.ts中定义了click事件类型因此回调参数e会被自动推断为MouseEventwindow.addEventListener(click, function (e) {}); // 推断出 e 的类型是 MouseEvent这解释了从值获取类型的另一个维度类型不仅来自值也来自值所处的上下文。二者结合构成了 TypeScript 完整而流畅的推断体系。六、进阶用typeof把值本身变成类型如果说前面几节是编译器自动推断那么typeof操作符则是主动从值提取类型的工具。在 《类型操作》章节 中本书展示了大量依托typeof与工具类型配合的值到类型应用。6.1 从函数返回类型提取ReturnTypeTtype Func (name: string) number; type MyType ReturnTypeFunc; // number6.2 从构造器提取参数与实例类型配合typeof可以从类值constructor 函数提取参数元组与实例类型class Person { constructor( public name: string, public age: number ) {} } type PersonConstructorParams ConstructorParameterstypeof Person; // [name: string, age: number] const params: PersonConstructorParams [John, 30]; const person new Person(...params); console.log(person); // Person { name: John, age: 30 }class Person { name: string; constructor(name: string) { this.name name; } sayHello() { console.log(Hello, my name is ${this.name}!); } } type PersonInstance InstanceTypetypeof Person; const person: PersonInstance new Person(John); person.sayHello(); // Hello, my name is John!这里typeof Person提取的是类的构造器函数值类型InstanceType...再从该构造器类型提取出实例类型——这是从值类定义到类型实例类型最典型的进阶应用。6.3 从函数值提取this类型interface Person { name: string; greet(this: Person): void; } type PersonThisType ThisParameterTypePerson[greet]; // Personfunction capitalize(this: String) { return this[0].toUpperCase() this.substring(1).toLowerCase(); } type CapitalizeType OmitThisParametertypeof capitalize; // () string6.4 从 Promise 值提取内部类型AwaitedT可以递归解包 Promise 类型常用于从异步值中提取最终类型type A AwaitedPromisestring; // string需要注意这里说的是类型空间的typeof用于类型位置它与运行时检查值的typeof操作符是两种不同语境下的同名语法本书在《探索类型系统》的类型缩小部分讨论的运行时typeof守卫不在此列。七、控制推断精度const 断言与类型参数 const 修饰符7.1 类型参数的const修饰符TypeScript 5.0在 《探索类型系统》章节 中本书展示了 TS 5.0 引入的泛型const修饰符如何让推断尽可能精确。先看不带const的情况function identityT(value: T) { // 这里没有 const return value; } const values identity({ a: a, b: b }); // 推断出的类型是 { a: string; b: string; }属性a、b被加宽为string。而加上const修饰符后function identityconst T(value: T) { // 在类型参数上使用 const 修饰符 return value; } const values identity({ a: a, b: b }); // 推断出的类型是 { a: a; b: b; }属性被精确推断为字符串字面量a、b——这与前面讲的从值获取类型一脉相承const修饰符阻止了泛型推断中的加宽让类型尽量贴近值本身。7.2 对象级别的as const断言as const断言用于把整个对象或数组视为不可变字面量本书给出了对象整体与元组的两个例子const v { x: 1, y: 2, } as const;const x [1, 2, 3]; // number[] const y [1, 2, 3] as const; // 只读元组 [1, 2, 3]as const之后数组被推断为精确的只读元组类型readonly [1, 2, 3]对象属性则全部成为字面量类型且带readonly修饰——这是从值获取类型时最有力的精度控制手段。7.3 显式类型注解兜底当自动推断无法满足需求时仍可显式给出注解。本书展示了通过联合字面量注解约束赋值范围const v: { x: 1 | 2 | 3 } { x: 1, // x 现在是字面量联合类型1 | 2 | 3 }; v.x 3; // Valid v.x 100; // Invalid至此从值获取类型的完整方法论已成型先依赖自动推断再在需要精确度时用const声明、as const断言、类型参数const修饰符收紧推断最后用显式注解兜底。八、小结把值到类型内化为开发直觉回顾《The Concise TypeScript Book》中关于 Type from Value 的系列内容可以总结出四条核心规律场景推断来源关键机制变量初始化字面量值const得字面量类型let加宽为基础类型对象属性属性字面量默认加宽用as const/as X收紧函数返回值函数实现自动推断无需注解模块导出导入导出值类型跨文件自动传递类型信息泛型调用实参值const T修饰符可阻止加宽其底层支撑来自 TypeScript 的类型推断引擎编译器分析值与表达式寻找最佳公共类型、运用上下文类型化并依据const/let的可变性语义决定加宽还是收窄。理解并主动运用这些规则你就能在少写注解与类型精确之间找到最佳平衡让 TypeScript 的类型系统真正为你服务。延伸阅读本书相关章节Type from Value日文原章节字面量推断函数返回值的类型模块的类型探索类型系统类型推断/加宽/const 断言类型操作typeof 相关工具类型赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐The Concise TypeScript Book从值推导类型Type from Value——TypeScript 类型推断机制与实战The Concise TypeScript Book从值推导类型Type from Value——TypeScript 类型推断机制与实战 导读 本篇文档教程从值推导类型深入解读 The Concise TypeScript Book 的 Type from Value 章节与类型推断机制从值推导类型深入解读 The Concise TypeScript Book 的 Type from Value 章节与类型推断机制 本篇以开源仓库 The文档教程The Concise TypeScript Book深入理解 Type from Value从值推断类型The Concise TypeScript Book深入理解 Type from Value从值推断类型 在《The Concise TypeScr文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考