)
教程【免费下载链接】typescript-book:books: The definitive guide to TypeScript and possibly the best TypeScript book :book:. Free and Open Source 项目地址https://gitcode.com/gh_mirrors/ty/typescript-book点击查看免费下载本文是 typescript-book 项目中「错误处理」章节docs/errors/common-errors.md的完整实战讲解聚焦开发者日常开发中最常遇到的几类 TypeScript 编译错误——未声明全局变量、缺失模块声明、模块编译开关缺失、catch 子句类型标注以及 React 声明文件重复等。读完本文你将掌握每类错误的根因、识别方法与标准修复流程并能结合 docs/errors/interpreting-errors.md 中介绍的错误解读方法在 IDE 中快速定位并修复自己的类型错误。一、先建立全局观TypeScript 错误信息是怎么组织的TypeScript 是一门以开发者帮助为核心设计导向的编程语言因此它的错误信息通常分为两个层次详见 docs/errors/interpreting-errors.md简洁版Succinct一行式描述包含错误码与概要信息例如TS2345: Argument of type ... is not assignable to parameter of type ...便于用错误码搜索同类问题。详细版Detailed在简洁版基础上追加一条WHY?因果链逐层拆解类型不兼容的根源例如Types of property bar are incompatible.之后继续追问Type () string is not assignable to type string.。IDE 的悬浮提示通常同时展示这两种形式日常排错时应主要阅读详细版并在脑中形成因果链。而本文要讲的 docs/errors/common-errors.md 则汇总了真实世界中最高频出现的几组错误码下面逐一展开。二、TS2304Cannot find name找不到名字错误示例Cannot find name ga Cannot find name $根因你正在使用某个第三方库例如 Google Analytics 的ga、jQuery 的$但该库没有被声明declare。TypeScript 之所以报错是它想帮你拦截两类低级问题拼写错误未声明就使用变量。因此凡是因为引入外部库而在运行时确实存在的全局名字你都必须显式地告诉 TypeScript即编写环境声明ambient declaration。在 code/errors/common-errors.ts 中就保留着这个错误的原始复现ga(); import {debounce} from underscore;在没有声明的情况下编译该项目使用 code/errors/tsconfig.json仅开启noEmit: true做类型检查第一行就会触发Cannot find name ga。如何修复使用 declare 关键字在 docs/types/ambient/d.ts.md 中给出了最直接的对照foo 123; // Error: foo is not defineddeclare var foo: any; foo 123; // allowed关于声明文件有几点重要约定环境声明既可以写在.ts文件中也可以写在.d.ts文件中真实项目强烈建议使用独立的.d.ts文件例如命名为global.d.ts或vendor.d.ts。如果文件扩展名是.d.ts那么每个根级定义都必须带declare前缀。这提醒作者TypeScript 不会为该文件发射任何代码作者必须自行保证被声明的实体在运行时真实存在。环境声明本质上是与编译器达成的承诺如果运行时并不存在这些实体却强行使用程序会在运行时静默出错。同时它也是一份文档源码变化后若声明未同步更新就会出现运行时正常但编译报错的中间状态见 docs/types/ambient/intro.md。推荐写法能用 interface 就不要用裸的any。例如 docs/types/ambient/variables.md 中对process变量的声明interface Process { exit(code?: number): void; } declare var process: Process;这样其他开发者可以通过 interface 合并declaration merging对全局变量进行扩展例如追加exitWithLogging方法同时仍保持类型安全。更多修复路径如果该库已在 types 生态如 DefinitelyTyped中提供类型优先npm install --save-dev types/库名并把声明文件纳入编译上下文参见 docs/types/ambient/d.ts.md 与 docs/project/compilation-context.md。若引入的是项目自身的全局脚本则在自己维护的global.d.ts中补上声明。三、TS2307Cannot find module找不到模块错误示例Cannot find module underscore根因你以模块方式使用某个第三方库例如import * as _ from underscore或import {debounce} from underscore但缺少对应的环境声明文件.d.ts。TS2304 针对的是全局变量场景而 TS2307 针对的是模块导入场景——两者唯一的差别在于使用方式修复思路一脉相承为库提供类型声明。同样在 code/errors/common-errors.ts 中import {debounce} from underscore;一行就是 TS2307 的复现样本。理解模块与全局命名空间为什么同样一个库写法不同错误就不同根源在 TypeScript 的模块体系docs/project/modules.md全局模块默认情况下新 TypeScript 文件中的代码处于全局命名空间。文件foo.ts里写了var foo 123;另一个文件bar.ts里就能直接使用foo尽管这有命名冲突风险。文件模块外部模块一旦文件根级出现import或export该文件就拥有了局部作用域不再污染全局。此时若想在bar.ts使用foo.ts导出的内容必须显式导入// foo.ts export var foo 123; // bar.ts import { foo } from ./foo; var bar foo; // allowedTS2307 正是导入语句存在但编译器找不到该模块的类型描述时的报错。修复方式安装官方/社区类型包对 underscore 这类流行库npm install --save-dev types/underscore即可参考 docs/types/types.md。为模块编写环境声明若没有现成类型可在.d.ts中声明模块详见 docs/types/ambient/d.ts.mddeclare module underscore { // 这里描述 underscore 的导出结构 }注意把声明文件放入编译上下文docs/project/compilation-context.md否则声明不会生效。四、TS1148Cannot compile modules unless the --module flag is provided错误示例Cannot compile modules unless the --module flag is provided根因代码中使用了外部模块文件含根级import/export但编译时没有指定--module标志编译器不知道要把模块编译成哪种 JavaScript 模块格式。修复为编译命令补上模块标志或在tsconfig.json的compilerOptions中显式配置module字段。module的取值包括commonjs、amd、system、umd、es2015/esnext等具体选择取决于目标运行环境{ compilerOptions: { module: commonjs, target: es5 } }说明module标志决定的是 TypeScript 文件编译后生成什么样的 JavaScript 模块语法它与 docs/project/modules.md 中讨论的文件模块概念直接相关——有模块就必须告诉编译器输出格式。Node.js 环境通常用commonjs浏览器打包场景视构建工具而定。为什么本项目示例没遇到 TS1148注意 code/errors/tsconfig.json 只设置了noEmit: true其用途是只做类型检查、不输出 JS。在noEmit模式下编译器不发射代码因此不会强制要求module标志但一旦你需要实际编译输出例如tsc生成 JS 文件就必须配置module。五、Catch 子句变量不能带类型标注错误示例try { something(); } catch (e: Error) { // Catch clause variable cannot have a type annotation }根因JavaScript 规范规定catch子句的变量不携带类型标注。TypeScript 在这里保护你免受现实世界中各类不规范 JS 代码的坑——你无法确定运行时 catch 到的究竟是不是Error实例因此类型系统不允许你武断地给e标注类型。修复改用类型守卫type guard。捕获后再用instanceof判断try { something(); } catch (e) { if (e instanceof Error){ // Here you go. 此时 e 被收窄为 Error 类型 } }instanceof是一种内建的类型守卫type guard能够把e从unknown/any收窄为Error。关于类型守卫的更多用法可参考 docs/types/typeGuard.md。补充在较新的 TypeScript 版本中未标注的catch (e)变量默认类型为unknown当useUnknownInCatchVariables开启时这意味着在判断之前直接访问e.message等属性本身就会报错——这恰好强化了先守卫、再使用的正确姿势。六、InterfaceElementClasscannot simultaneously extend typesComponentandComponent错误示例Interface ElementClass cannot simultaneously extend types Component and Component根因编译上下文中出现了两个react.d.ts即两份types/react/index.d.tsTypeScript 无法决定该采用哪一份于是报出同一个接口同时扩展了两个同名类型的错误。标准修复流程重装依赖删除node_modules删除package-lock.json或 yarn.lock然后重新执行npm install或对应包管理器命令以消除重复/残留的类型包。若仍无效找出那个非法的模块——项目中所有依赖react的模块都应把types/react声明为peerDependency对等依赖而不是硬编码的dependency。某个包如果把types/react写进了自己的dependencies就会导致重复安装。找到该模块后应到其项目仓库反馈问题要求其修正依赖声明方式。为什么重复声明会引发这个错误TypeScript 的**接口合并declaration merging**机制允许同名 interface 合并但extends一个模棱两可的基类时编译器必须能解析出唯一的类型来源。当node_modules中存在两份types/react/index.d.ts例如版本冲突或依赖树嵌套导致重复拷贝时类型解析出现歧义合并规则被破坏于是报出同时扩展两个 Component的错误。这也提示我们保持依赖树的干净单一版本对 TypeScript 类型解析至关重要。七、结合 IDE 的完整排错流程把上面的错误知识串起来一套可复用的排错流程是阅读详细版错误在脑中形成 ERROR → WHY? → CAUSE ERROR → WHY? → ... 的因果链定位到具体属性或表达式方法见 docs/errors/interpreting-errors.md。记录错误码如TS2304、TS2307用错误码搜索同类问题的资料命中率高且信息噪音小。对照本文的分类表判断根因类别全局名字未声明 → 补环境声明TS2304模块缺少类型声明 → 安装 types 或写declare moduleTS2307模块未配置编译格式 → 配置moduleTS1148catch 变量带标注 → 去掉标注改用类型守卫React 相关重复声明 → 重装依赖、检查 peerDependency。项目源码中code/errors/common-errors.ts 与 code/errors/interpreting-errors.ts 分别保留了两类错误的最小复现样本前者演示 TS2304/TS2307后者演示bar: getBar忘记调用导致的 TS2345 类型不兼容配合 code/errors/tsconfig.jsonnoEmit: true纯类型检查即可在本地亲手触发并观察这些错误从而加深理解。小结本文覆盖了 docs/errors/common-errors.md 中全部五类高频错误TS2304全局名字未声明、TS2307模块缺声明、TS1148模块缺编译格式、catch 子句变量类型标注、以及React 声明文件重复。它们的共同底层逻辑是TypeScript 的声明优先设计——无论是全局变量还是模块凡是运行时存在的东西都需要通过环境声明显式告知编译器凡是模块输出都需要明确编译格式。掌握这一逻辑再配合 docs/errors/interpreting-errors.md 的因果链解读法你就能在 IDE 中快速定位并修复绝大多数日常类型错误。赞分享教程【免费下载链接】typescript-book:books: The definitive guide to TypeScript and possibly the best TypeScript book :book:. Free and Open Source 项目地址https://gitcode.com/gh_mirrors/ty/typescript-book点击查看免费下载相关推荐TypeScript 错误全解析读懂编译器报错信息与高频常见错误修复指南TypeScript Deep DiveTypeScript 错误全解析读懂编译器报错信息与高频常见错误修复指南TypeScript Deep Dive TypeScript 是一门以开发者帮教程如何解决Immersive Translate沉浸式翻译的7个典型问题如何解决Immersive Translate沉浸式翻译的7个典型问题 Immersive Translate沉浸式翻译是一款功能强大的双语网页翻译扩展能够实前端AI 应用Sim 项目 React Query 最佳实践审计指南Key Factory、staleTime、Mutation 与服务器状态所有权Sim 项目 React Query 最佳实践审计指南Key Factory、staleTime、Mutation 与服务器状态所有权 本指南基于 Sim 仓教程上一篇lax.js第三方工具集成从设计到开发的工作流下一篇Private Bower源码解析核心模块与包管理机制的实现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考