
文档教程【免费下载链接】typescript-book-chineseTypeScript Deep Dive 中文版项目地址https://gitcode.com/gh_mirrors/ty/typescript-book-chinese点击查看免费下载TypeScript 的核心价值在于其静态类型系统。本文基于《深入理解 TypeScript》中文版typescript-book-chinese的「类型系统概览」章节系统讲解从基础类型注解到接口、泛型、联合类型、交叉类型、元组与类型别名的完整知识链并结合仓库内 docs/typings 系列文档的源码级示例帮助读者掌握给 JavaScript 代码添加类型并从中受益的全部核心语法为后续深入理解类型系统如 类型兼容性、类型推断、环境声明打下坚实基础。TypeScript 类型系统的设计哲学在讨论为什么使用 TypeScript 时我们需要先理解其类型系统的两个关键设计原则类型系统是可选的你的 JavaScript 本身就是合法的 TypeScript未注解的代码不会报错这让已有 JS 项目可以零成本起步类型错误不会阻止 JavaScript 运行即使存在类型错误编译产物依然可以执行。这一点让「逐步迁移」成为现实——你可以先把.js改成.ts再一块一块地补上类型注解而不是一次性重写整个项目。理解这两条原则非常重要因为它们决定了 TypeScript 的迁移路径是渐进式的、低风险的。在此基础上本概览将带你学习类型系统的语法如何给代码加上类型注解以及能获得哪些实实在在的益处。基本注解TypeAnnotation语法TypeScript 使用:TypeAnnotation语法进行类型注解。只要该内容存在于类型声明空间中就可以作为类型注解使用。下面的例子同时注解了变量、函数参数和函数返回值const num: number 123; function identity(num: number): number { return num; }这种「注解即文档」的写法让编译器和阅读代码的人都能明确知道变量与函数的边界约束。更完整的函数参数与返回值注解用法可参考 docs/typings/functions.md包括可选参数、默认值与函数重载。原始类型string、number、booleanJavaScript 的原始类型同样适用于 TypeScript 类型系统string、number、boolean可以直接用作类型注解。赋值错误类型时会立刻得到编译错误let num: number; let str: string; let bool: boolean; num 123; num 123.456; num 123; // Error str 123; str 123; // Error bool true; bool false; bool false; // Error这里的关键在于类型注解不是运行时约束而是编译期的静态检查。错误在编译阶段即被暴露而不是等到运行时才崩溃。数组类型后缀[]语法TypeScript 为数组提供了专用的类型语法——后缀[]你可以根据需要补充任何有效的类型注解如:boolean[]。它能让你安全地使用任何数组操作同时防止把错误类型的值赋给数组成员let boolArray: boolean[]; boolArray [true, false]; console.log(boolArray[0]); // true console.log(boolArray.length); // 2 boolArray[1] true; boolArray [false, false]; boolArray[0] false; // Error boolArray false; // Error boolArray [true, false]; // Error可以看到无论是给单个成员赋错类型、把整个数组赋成字符串还是往数组里塞进一个错误类型的元素都会被编译器拦截。接口合并类型声明接口interface是 TypeScript 的核心知识之一它能将众多类型声明合并进一个类型声明中从而强制对每个成员进行类型检查interface Name { first: string; second: string; } let name: Name; name { first: John, second: Doe }; name { // Error: Second is missing first: John }; name { // Error: Second is the wrong type first: John, second: 1337 };在这里first: stringsecond: string被合并进了新的类型注解Name缺字段、字段类型错误都会被编译器拒绝。关于接口更深入的内容开放合并、implements类实现、声明任意 JS 结构等见 docs/typings/interfaces.md。内联类型注解{ /*Structure*/ }与创建接口不同你可以使用内联注解语法注解任何内容:{ /*Structure*/ }let name: { first: string; second: string; }; name { first: John, second: Doe }; name { // Error: Second is missing first: John }; name { // Error: Second is the wrong type first: John, second: 1337 };内联类型的价值在于快速省去为类型起名的麻烦尤其是当你可能起一个很糟糕的名字时。但如果你发现需要多次重复使用同一个内联注解就应该考虑把它重构为接口或类型别名type alias见下文。特殊类型any、null、undefined、void除原始类型外TypeScript 还有几个特殊类型它们在类型系统中扮演着不同的角色。any类型系统的「后门」any在 TypeScript 类型系统中占有特殊地位——它提供了一条类型系统的「后门」TypeScript 会为标注为any的值关闭类型检查。在类型系统里any兼容所有类型包括它自己因此所有类型都能赋值给它它也能赋值给其他任何类型let power: any; // 赋值任意类型 power 123; power 123; // 它也兼容任何类型 let num: number; power num; num power;在把 JavaScript 迁移至 TypeScript 的过程中any会被频繁使用。但你必须尽量减少对它的依赖使用any基本上等于告诉编译器不要进行任何类型检查这会削弱类型安全。迁移的最终目标应该是用精确类型逐步替换掉any。null 和 undefined在类型系统中JavaScript 的null和undefined字面量与其他被标注为any类型的变量一样都能被赋值给任意类型的变量在strictNullChecks未开启的默认行为下// strictNullChecks: false let num: number; let str: string; // 这些类型能被赋予 num null; str undefined;需要留意的是一旦开启strictNullChecks编译选项null与undefined将不再能随意赋给其他类型这能捕获大量潜在的空值错误——这是现代 TypeScript 工程中推荐开启的严格模式开关之一。void表示没有返回值使用:void表示一个函数没有任何返回值function log(message: string): void { console.log(message); }正如 docs/typings/functions.md 所说明的通常你可以在函数不返回任何内容时省略void注解由 TypeScript 自动推导。泛型在成员之间提供约束在计算机科学中许多算法和数据结构并不依赖于对象的实际类型但你仍然希望在每个变量上强制提供约束。例如一个函数接受一个列表并返回这个列表的反向排序这里的约束就是「传入参数的类型与函数返回值的类型一致」function reverseT(items: T[]): T[] { const toreturn []; for (let i items.length - 1; i 0; i--) { toreturn.push(items[i]); } return toreturn; } const sample [1, 2, 3]; let reversed reverse(sample); console.log(reversed); // 3, 2, 1 // Safety reversed[0] 1; // Error reversed [1, 2]; // Error reversed[0] 1; // ok reversed [1, 2]; // ok在上例中函数reverse接受一个类型为T注意reverseT中的类型参数的数组items: T[]返回类型同样为T[]。当你传入const sample [1, 2, 3]时TypeScript 会推断出reverse的返回类型为number[]从而提供类型安全。同理传入string[]时它推断出string[]const strArr [1, 2]; let reversedStrs reverse(strArr); reversedStrs [1, 2]; // Error事实上JavaScript 数组已经拥有reverse方法而 TypeScript 正是用泛型来定义其结构的interface ArrayT { reverse(): T[]; }这意味着当你调用数组的.reverse()方法时同样能获得类型安全let numArr [1, 2]; let reversedNums numArr.reverse(); reversedNums [1, 2]; // Error关于ArrayT的更多讨论会在 docs/typings/ambient.md 的lib.d.ts部分展开。若想深入学习泛型的设计动机如用泛型类实现类型安全的队列、泛型误用陷阱与「方便通用」设计模式可阅读 docs/typings/generices.md。联合类型string | number在 JavaScript 中你常常希望某个属性是多种类型之一例如字符串或者数组。这正是 TypeScript 联合类型的用武之地——它使用|作为标记如string | number。一个典型用例是一个函数可以接受字符串数组也可以接受单个字符串function formatCommandline(command: string[] | string) { let line ; if (typeof command string) { line command.trim(); } else { line command.join( ).trim(); } // Do stuff with line: string }配合typeof收窄type guard联合类型让「多种形态输入」的函数既灵活又安全。更系统的类型守卫知识参见 docs/typings/typeGuard.md。交叉类型T U在 JavaScript 中extend是一种非常常见的模式从两个对象创建出一个新对象新对象拥有两个对象的所有功能。交叉类型T U可以让你安全地使用这种模式function extendT extends object, U extends object(first: T, second: U): T U { const result T U{}; for (let id in first) { (Tresult)[id] first[id]; } for (let id in second) { if (!result.hasOwnProperty(id)) { (Uresult)[id] second[id]; } } return result; } const x extend({ a: hello }, { b: 42 }); // 现在 x 拥有了 a 属性与 b 属性 const a x.a; const b x.b;返回类型T U意味着结果对象同时具备T与U的全部成员x.a与x.b都能被类型安全地访问。元组类型[typeofmember1, typeofmember2]JavaScript 本身并不支持元组开发者通常只能用数组表示元组。TypeScript 则原生支持元组类型你可以使用:[typeofmember1, typeofmember2]的形式为元组添加注解元组可以包含任意数量的成员let nameNumber: [string, number]; // Ok nameNumber [Jenny, 221345]; // Error nameNumber [Jenny, 221345];将元组与解构一起使用可以优雅地取出具名变量let nameNumber: [string, number]; nameNumber [Jenny, 322134]; const [name, num] nameNumber;类型别名type SomeName someValidTypeAnnotationTypeScript 提供了为类型注解设置别名的便捷语法type SomeName someValidTypeAnnotation。type StrOrNum string | number; // 使用 let sample: StrOrNum; sample 123; sample 123; // 会检查类型 sample true; // Error与接口不同你可以为任意类型注解提供类型别名这在联合类型和交叉类型中尤为实用。下面是一些熟悉别名语法的示例type Text string | { text: string }; type Coordinates [number, number]; type Callback (data: string) void;接口还是类型别名如何选择官方概览给出如下实践建议如果你需要使用类型注解的层次结构请使用接口——接口能使用implements和extends为简单的对象类型如上面的Coordinates使用类型别名只需给它一个语义化的名字即可当你想给联合类型或交叉类型提供语义化名称时类型别名是更好的选择。值得补充的是接口还具有「开放合并」的特性相同名字的接口声明会自动合并这使其能模仿 JavaScript 对象在运行时被逐步扩展的灵活性具体见 docs/typings/interfaces.md。后续学习路线至此你已经能够为大部分 JavaScript 代码添加类型注解。接下来可以沿着 docs/typings 目录继续深入 TypeScript 类型系统接口详解开放合并、implements与类的实现约束泛型深入泛型队列、getJSONT与 axios 配合的实战范式函数类型参数注解、返回类型、可选参数、默认值与重载环境声明用declare安全使用现有 JavaScript 库类型推断、类型兼容性、类型守卫理解类型系统更深层的运作机制。这些章节共同构成了《深入理解 TypeScript》中文版的完整类型系统知识体系适合从本文的「概览级」知识平滑过渡到「原理级」理解。赞分享文档教程【免费下载链接】typescript-book-chineseTypeScript Deep Dive 中文版项目地址https://gitcode.com/gh_mirrors/ty/typescript-book-chinese点击查看免费下载相关推荐craft.js的TypeScript高级类型泛型与接口设计craft.js的TypeScript高级类型泛型与接口设计 概述 craft.js作为一个React框架提供了强大的拖放页面编辑器功能。其TypeScri前端深入探索 TypeScript 类型系统《The Concise TypeScript Book》类型系统章全解析深入探索 TypeScript 类型系统《The Concise TypeScript Book》类型系统章全解析 本篇指南以开源仓库 The Concise文档教程Project-Based-Learning类型安全TypeScript类型系统和泛型Project Based Learning类型安全TypeScript类型系统和泛型 引言为什么JavaScript开发者需要TypeScript 你是文档教程上一篇astronAgent 完整部署实战指南Casdoor 认证、RagFlow 知识库与核心服务集群的 Docker Compose 编排下一篇终极指南JWT令牌吊销与黑名单机制完全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考