从 JavaScript 到 TypeScript:类型系统如何重塑前端工程化实践
1. 为什么从 JavaScript 走向 TypeScript这不是选择题是必然结果先聊点实在的。我最早写 JavaScript 的时候和大多数人一样觉得这门语言真自由对象随便造函数随便传没人管你传的是字符串还是数字。直到有一次接手一个跑了两年多的项目一个核心模块里存了用户信息代码里到处都在用这个对象结果某个字段因为拼写错误线上跑了一个星期才在某个边缘场景里炸出来。排查那个 bug 花了我差不多三天时间最后发现只是某个对象属性名少写了一个字母。那种感觉真的就是一个字母毁掉整个周末。后来我认真想了想JavaScript 本身没有错它只是把类型检查这件事完全交给了运行时。你传错了类型它不吭声等真正执行到那行代码才发现哦这里不是个函数那里没有这个方法。浏览器和 Node 这些运行时能做的最多就是抛个 TypeError但问题在于错误发生的时机太晚了。而 TypeScript 做的事情本质上就是把这种错误从运行时提前到编译期让你在敲键盘的时候就能看到红色波浪线。先说清楚 TypeScript 是什么它是 JavaScript 的一个超集由微软在 2012 年开始开发2014 年正式对外发布。所有合法的 JavaScript 代码它都支持然后在这个基础上加了一套完整的静态类型系统。你写 TypeScript本质上还是在写 JavaScript只是多写了类型标注多了一层编译检查。最后编译出来的产物还是纯 JavaScript可以在任何支持 JS 的环境里运行。它能解决什么问题最核心的就是三类第一类型错误在开发阶段就被拦截第二IDE 可以根据类型定义给出精准的补全和提示这个体验提升是肉眼可见的第三代码结构本身变成了一种活文档别人接手你的代码看到函数签名就知道该传什么参数、返回什么类型不用再一层一层翻实现。谁适合学 TypeScript我的答案是所有写过一定量 JavaScript 的人。尤其是写 React 或 Vue 这类框架项目的还有做 Node 后端开发的以及项目规模超过一个人、需要团队协作的场景。如果你只是写个几行脚本、做个简单的页面交互那 TypeScript 的收益确实不明显毕竟多写几个类型标注也有学习成本。但只要你开始维护一个真正会持续演进的项目TypeScript 带来的收益会随着项目规模指数级放大。下面这篇文章我会从一个实际开发者的角度把从 JavaScript 过渡到 TypeScript 的过程中最核心的东西拆开讲清楚。文章不会只停留在语法层面更多的是我踩过坑之后总结出来的实战经验。2. 环境搭建与编译链路先把地基打牢很多人学 TypeScript 卡在第一步不是语法难而是不知道怎么把它跑起来。其实整个过程没有你想得那么复杂核心就三件事装编译器、写配置、跑编译。2.1 从安装到第一次编译你需要的全部命令先确保你已经装了 Node.js版本建议 LTS 以上然后全局安装 TypeScript 编译器npm install -g typescript装完验证一下tsc --version能看到版本号就说明编译器装好了。接下来创建一个测试目录简单写一个 TypeScript 文件试试mkdir ts-demo cd ts-demo新建一个hello.tsfunction greetings(name: string): string { return Hello, ${name}!; } const result greetings(TypeScript); console.log(result);这里注意看两个地方函数参数name后面用了: string返回值括号后面也用了: string。这就是类型标注告诉编译器这个函数接收一个字符串参数返回一个字符串结果。然后执行编译tsc hello.ts你会发现目录下多了一个同名hello.js文件这就是编译产物。Node 直接运行它node hello.js输出Hello, TypeScript!第一次编译就完成了。这里有个很多人没意识到的点TypeScript 的编译是类型擦除式的。它是把类型标注删掉再把一些现代语法转译成目标版本的 JavaScript而不是像其他语言那样真的生成一套新的运行时。所以编译出来的 JS 文件本质上就是你手写 JS 也会写出来的样子。2.2 tsconfig.json 的核心配置别再默认设置裸奔了单文件编译只是开胃菜。真实项目里你需要一个配置文件来控制整个工程的编译行为。执行tsc --init会生成一个tsconfig.json里面默认带了大量注释项。我第一次看到这个文件的时候是真头疼几十个配置项根本不知道哪些该开哪些该关。这里我直接给你整理成一张速查表是我实际项目里最常用的一组配置配置项我的推荐值作用说明targetES2020编译输出的 JavaScript 版本决定了语法转译到什么程度moduleESNext模块系统写前端项目时配合打包器用 ESNext 就行stricttrue开启所有严格类型检查选项这个必须开moduleResolutionbundler或node模块解析策略配合你的项目环境选esModuleInteroptrue让 CommonJS 和 ES Module 之间能正常互操作skipLibChecktrue跳过对.d.ts声明文件的类型检查能显著加快编译速度forceConsistentCasingInFileNamestrue强制文件名大小写一致跨平台协作时很有用outDir./dist编译产物输出目录rootDir./src源码目录编译后会保持目录结构sourceMaptrue生成 source map调试时能映射回 TS 源码强调一下strict这一项别想着先关掉以后再开。我见过太多项目一开始图省事把strict设成false写了两三个月后想开回来结果满屏报错改得想死。我的建议是从第一天就把它开着哪怕初期多花点时间写类型也比后期回头填坑强得多。2.3 把编辑器变成你的第一道防线配置好编译环境之后还有一个能极大提升体验的事让编辑器在保存文件的时候就给出类型反馈。以我一直用的 VS Code 来说它内置了对 TypeScript 的支持只要项目里有tsconfig.json你在写代码的时候就能实时看到类型错误。这里有个容易被忽略的小技巧VS Code 的自动导入和重构功能对 TypeScript 的支持是所有语言里最好的。你可以试试把一个变量重命名编辑器会智能地同步修改所有引用包括跨文件的。这在纯 JavaScript 项目里是做不了的但对 TypeScript 是标配。另外一个很实用的配置是保存时自动编译。在 VS Code 的终端里执行tsc --watch编译器就会进入监听模式你每次保存.ts文件它自动重新编译有报错直接打在终端里。开发的时候我基本一直挂着这个进程。3. 类型系统核心概念这些基础知识决定了你的上限环境搞定了接下来就是最核心的部分TypeScript 的类型系统。这一部分我不打算按官方文档的顺序给你罗列一遍那没意义。我按照实际开发中遇到的频率来拆解。3.1 基础类型与对象类型从感叹号到舒适区JavaScript 里的原始类型TypeScript 都有对应的类型标注// 基本类型 const name: string 张三; const age: number 28; const isActive: boolean true; const data: null null; let content: undefined undefined; const big: bigint 9007199254740993n; const sym: symbol Symbol(key);这里有个细节值得注意string是小写开头的不是String。大写开头的String在 TypeScript 里是包装对象类型实际开发中你几乎永远用不到。比较常见的坑是新手写String结果某些场景类型对不上。记住一个原则基础类型永远用小写的那套。数组有两种写法const arr1: number[] [1, 2, 3]; const arr2: Arraynumber [1, 2, 3]; // 泛型写法后面会细说元组类型约束了数组每个位置的类型const tuple: [string, number] [id, 18];对象类型是日常最常用的interface User { id: number; name: string; email?: string; // 问号表示可选属性 readonly createdAt: Date; // readonly 表示只读不可修改 }这里有两个点要展开说。第一是?:可选属性它和undefined联合类型在语义上略有区别但大多数场景下够用。第二是readonly它防止的是编译期的属性修改不是运行时的冻结。如果你在代码里试图给readonly属性赋值编辑器会在写代码的时候直接提醒你。在真实业务里我更建议你给每个核心数据模型都定义接口比如用户、订单、商品这些。这会在后面的开发中省掉大量这个对象到底有哪些字段的记忆成本。3.2 接口interface与类型别名type到底怎么选两个东西都能定义对象结构它们之间的区别经常被问起。简单说三点interface可以被重复声明合并属性和方法type不能重复声明。interface支持继承extendstype需要借助交叉类型来组合。type可以描述联合类型、元组、原始类型等接口无法描述的东西。我从项目实践的角度给你一个决策标准定义对象的结构用interface需要组合类型或描述联合类型用type。这个规则能覆盖 90% 的场景。实际演示一下// interface 的扩展 interface BasicUser { id: number; name: string; } interface AdminUser extends BasicUser { permissions: string[]; } // type 的组合 type ID string | number; type Point { x: number; y: number }; type NamedPoint Point { name: string };3.3 类型推断与联合类型让编译器替你干活TypeScript 的强大一半在类型推断。你不一定非得给每个变量都写类型标注编译器会根据赋值自动推断let count 10; // 自动推断为 number let message hello; // 自动推断为 string但如果声明时不赋值或者赋值为一个可变联合类型情况就变了let val: string | number; // 联合类型 val hello; // 合法 val 42; // 合法这里的|就是联合类型操作符表示或的关系。在实际开发中联合类型最常见于函数参数一个函数可能接收多种类型的输入function formatId(id: string | number): string { return ID: ${id}; }不过要注意一个细节当函数内部使用联合类型参数时你可能需要先收窄类型。收窄最常用的方式是typeof判断function formatId(id: string | number): string { if (typeof id string) { return id.toUpperCase(); } return id.toString(); }编译器很聪明它在if分支里能自动识别出id在这个作用域内是string类型这就是类型收窄。3.4 泛型最值得花时间啃下来的部分泛型是 TypeScript 类型系统里最难理解、但也是回报最高的特性。用一句话解释泛型就是类型的参数。就是你写函数的时候不限定参数的具体类型而是让调用方来决定。举个例子一个获取数组第一个元素的函数function firstElementT(arr: T[]): T | undefined { return arr[0]; } const num firstElementnumber([1, 2, 3]); // 返回 number const str firstElementstring([a, b]); // 返回 stringT就是泛型参数。调用时传入具体的类型函数内部就能保持类型的统一。这个能力在封装通用逻辑时极其有用比如一个获取接口数据的通用函数async function fetchDataT(url: string): PromiseT { const res await fetch(url); return res.json() as PromiseT; } interface OrderInfo { orderId: string; amount: number; } fetchDataOrderInfo(/api/order/123).then((data) { console.log(data.amount); // 智能提示出 amount 是 number });你可以把泛型理解为一个类型层面的参数传递调用方传什么类型函数就返回什么类型。这样既保住了灵活性又没丢掉类型安全。泛型还有一个重要用途是约束。你可以给泛型加条件要求传入的类型必须满足某些结构interface HasLength { length: number; } function logLengthT extends HasLength(arg: T): void { console.log(arg.length); } logLength(hello); // 合法string 有 length logLength([1, 2, 3]); // 合法数组有 length logLength(42); // 报错number 没有 length4. 工程化实践与进阶玩法真正把 TypeScript 用起来语法学过之后真正决定你能不能把 TypeScript 用好的是工程化的部分。这一章聊几个关键实践。4.1 开启 strict 模式把隐患消灭在编译期前面已经强调了strict要开但你可能不知道它具体开启了一组什么检查。strict不是单个配置项它包含noImplicitAny、strictNullChecks、strictFunctionTypes等一堆子项。这里我就挑影响最大的strictNullChecks说。在没有strictNullChecks的时候null和undefined可以赋值给任何类型。这就意味着你声明一个变量是string但它的实际值可能是null运行时调toUpperCase()就炸了。开启strictNullChecks后null和undefined不能随便赋值给普通类型你必须显式使用联合类型let nickname: string | null null; // 显式允许为 null这个配置强制你去考虑这个值可能为空的情况写出来的代码在运行时会稳很多。我接手过没开这个检查的项目线上偶发报错排查了半天最后发现是某个接口返回了null代码里直接当成对象用了。4.2 声明文件与第三方库遇到没有类型的 JS 库怎么办你在项目里必然要用第三方库大部分主流库自己带了.d.ts声明文件装完就有类型支持。但总有少数库没有类型这时候你就得自己写声明。.d.ts文件的后缀叫声明文件它只包含类型定义不包含实现逻辑。举个简单例子假设你的项目里用了一个老的 JS 工具库legacy-tool它提供了一个formatMoney函数。你可以新建一个legacy-tool.d.tsdeclare module legacy-tool { export function formatMoney(amount: number, currency?: string): string; }这样在代码里导入这个库时TypeScript 就知道formatMoney的签名了不用再到处any。如果你实在懒得写可以用npm install types/xxx装社区维护的声明文件。types这个作用域底下是 DefinitelyTyped 社区持续维护的第三方类型声明合集。4.3 与主流前端框架配合的常见姿势现在几乎没人用纯 TypeScript 写前端界面了都是配合框架。以我用得最多的 React 举例常见的套路是给组件的 props 定义接口interface Props { title: string; count: number; onUpdateCount: (newCount: number) void; } function CounterCard({ title, count, onUpdateCount }: Props) { return ( div h2{title}/h2 p当前计数{count}/p button onClick{() onUpdateCount(count 1)}增加/button /div ); }这样定义之后在使用CounterCard的地方编辑器会给出完整提示props 必须有title、count、onUpdateCount而且各自类型要对上。组件之间的数据流一目了然再也不用去翻组件内部实现来猜该怎么用。Vue 3 的script setup语法对 TypeScript 的支持也很好核心是给组件的 props 和 ref 标注类型。不管用什么框架核心思路是一致的用 TypeScript 的类型系统把组件之间传的值全部约束起来。4.4 几个能提升工作效率的工具类型除了自己定义类型TypeScript 还内置了一组工具类型能帮你从已有类型中衍生出新类型。日常用得最多的这几个我直接列出来interface Order { id: string; productName: string; price: number; quantity: number; createdAt: Date; } // 全部属性变为可选 type PartialOrder PartialOrder; // 全部属性变为必选 type RequiredOrder RequiredPartialOrder; // 只保留指定的属性 type OrderBasicInfo PickOrder, id | productName | price; // 剔除指定的属性 type OrderWithoutDate OmitOrder, createdAt; // 生成一个键为 string、值为 number 的对象类型 type Dictionary Recordstring, number;这些工具类型本质上是用泛型加条件类型组合出来的你在日常开发中不需要自己实现它们但要清楚它们能干什么能省掉大量重复的手写类型定义。比如后端接口返回的分页数据结构我用Pick从一个完整的实体类型中提取出列表需要的字段这样一行代码就能搞定一个精准的列表项类型。5. 常见问题与排查技巧实录我踩过的坑你就别踩了任何语言学到一定深度都会遇到一堆让人抓狂的问题。这一章我整理了自己在真实项目中遇到的最高频问题直接列成速查表配合排查思路讲。5.1 高频报错速查表报错提示原因解决方案Type undefined is not assignable to type string没开strictNullChecks时不会报的错开了之后强制你处理 undefined用联合类型string | undefined或者在赋值为string类型前做空值判断Property xxx does not exist on type {}你访问了一个空对象上不存在的属性通常是类型推断不完整给对象定义接口类型Argument of type string is not assignable to parameter of type number函数参数类型不匹配检查调用处传入的实际类型通常是把number当成了stringCannot find module xxx or its corresponding type declarations第三方库没有自带类型声明全局也没有对应types安装types/xxx或者自己补.d.ts声明文件xxx is possibly null值可能为 null需要收窄if (xxx null) return;或用可选链?.这里面最常踩的就是第一个和最后一个根子都在strictNullChecks上。我的经验是开启了这个检查之后写函数的第一步就是考虑边界输入是null或undefined时怎么办。时间长了会形成肌肉记忆代码质量提升非常明显。5.2 三个必须避免的反模式反模式一疯狂使用any。一开始写 TypeScript 的时候遇到类型报错最顺手的解决办法就是as any。这确实能绕过所有检查但等于把 TypeScript 变成了带注释的 JavaScript。一个项目里any多了类型系统的价值就归零了。我的建议是用unknown代替anyunknown至少强制你进行类型收窄才能使用具体的值。反模式二到处用as强行断言。类型断言是把双刃剑它告诉编译器你信我我知道它是什么类型。问题是如果你的判断有误运行时就会炸。合理的使用方式是在边界处做一次断言配合运行时校验不合理的用法是每个函数参数都要as一下来消除报错。出现大量断言通常意味着你的类型设计有问题。反模式三暴力ts-ignore。这个注释会直接跳过整行代码的类型检查。偶尔在特殊场景用一次可以理解但如果你发现项目里ts-ignore越来越多就该停下来认真审视类型问题了。它不像any那样有可见性它是直接隐形的。5.3 排查类型问题的一个高效思路遇到一个类型报错不要急着改代码。先做三步排查第一步看报错位置是在定义处还是使用处。定义处的报错通常是类型本身设计有问题使用处的报错通常是类型没有对齐。第二步把鼠标悬停在出问题的变量上查看 TypeScript 自己推断出的类型是什么。很多时候你会发现它推断出来的类型和你以为的类型完全不一样。第三步最小化复现。如果你遇到的是一个复杂的泛型类型报错试着在一个独立的小文件里复现出同样的用法这样能更快定位问题。写给你的几个真心建议从 JavaScript 过渡到 TypeScript我个人的体会是它不是一个学完就完事的东西更要紧的是养成写代码时多想一步的习惯。类型标注只是表象背后是对数据流的重新梳理。每当你写下一个接口定义、一个泛型约束你其实是在给代码的调用方、给未来的自己立规矩。在项目里我比较推荐渐进式迁移的路线不需要一夜之间把所有 JS 文件都改成 TS可以从一个核心模块开始先建好tsconfig.json、开严格模式、给核心数据模型补类型跑通之后再逐步扩大范围。这个过程会有点痛但收益是成块的。最后分享一个我在观望阶段一直纠结的问题是不是所有场景都值得用 TypeScript我现在给出的答案是八二开——对绝大多数中大型项目、持续迭代的项目、多人协作的项目值得对一次性脚本、几十行的临时工具函数不值得。用 TypeScript 不是目的写出更稳、更好维护的代码才是目的。如果你刚开始转型遇到类型报错不要慌大部分报错信息其实写得很精准英文读不快也没关系先把报错里的文件路径变量名期望类型实际类型四个信息找出来90% 的问题都能在这个框架内解决。剩下的 10%搜索引擎和社区里几乎都有现成答案。这条进阶之路不会特别平缓但走完回头看你会庆幸自己没停留在能跑就行的舒适区。

相关新闻

Spark submit求PI实战:掌握分布式计算核心原理

Spark submit求PI实战:掌握分布式计算核心原理

1. 项目概述:用Spark submit跑一个“求PI”的经典分布式计算实验你可能在刚接触大数据生态时,就听过这么一句话:“学Spark,先跑通WordCount;想摸清调度和执行模型,就得亲手提交一次求PI任务。”这个标题里的…

2026/10/13 11:36:08 阅读更多 →
意图识别实战:从概念到落地的工程经验总结

意图识别实战:从概念到落地的工程经验总结

意图识别这四个字,刚入行的时候我觉得它特别虚。不就是分个类吗,文本扔进去,标签吐出来,能有多难。后来真正在项目里踩了一圈坑才发现,这东西远没有想象中那么简单。用户说“我想把昨天买的那件衣服退了”,…

2026/10/13 11:35:03 阅读更多 →
Hive小时任务调度:Shell封装实现精准时间窗口与容错执行

Hive小时任务调度:Shell封装实现精准时间窗口与容错执行

1. 项目概述:为什么“按小时循环执行Hive脚本”不是简单加个crontab就完事?在某数据中台团队的实际运维场景里,我接手过一个典型的准实时ETL任务:上游业务系统每小时生成一批原始日志文件,存入HDFS指定路径&#xff1b…

2026/10/13 11:35:03 阅读更多 →

最新新闻

CATIA V5R13汽车线束设计:三维布线到展平BOM的避坑指南

CATIA V5R13汽车线束设计:三维布线到展平BOM的避坑指南

简介:针对CATIA V5R13汽车线束设计的PPT课件,面向电气工程初学者与CATIA V5新用户,系统讲解线束在数字样机中的创建、装配与连接方法。在整车开发中,线束承担汽车电气系统中电能与信号传输,设计质量直接影响整车布线合…

2026/10/13 14:21:17 阅读更多 →
机器学习从入门到精通:一份带路标的实操地图

机器学习从入门到精通:一份带路标的实操地图

经常被问到同一个问题:学Python机器学习,到底怎么从入门走到精通?问的人五花八门,有想转行的程序员,有在校学生,也有做数据分析正考虑转型的同事。大家手里不缺教程,收藏夹里躺着几十个视频和几…

2026/10/13 14:21:17 阅读更多 →
新人接手项目管理:第一周先做三张表,快速建立掌控感

新人接手项目管理:第一周先做三张表,快速建立掌控感

1. 新人接手项目管理的真实困境:不是不会管,是不知道先管什么刚入职不久就被拉进项目群、丢过来一份需求文档、告诉你"这个项目你来跟",这种场景在不少公司都挺常见。尤其是节奏快、业务复杂度高的环境里,新人往往还没搞…

2026/10/13 14:21:17 阅读更多 →
三月份实习笔记:数据整理、需求梳理与竞品调研的实战复盘

三月份实习笔记:数据整理、需求梳理与竞品调研的实战复盘

1. 三月份实习笔记的缘起与记录逻辑三月份是很多团队一年中节奏切换最明显的节点。春节后的复工潮刚过,年度目标已经拆解到季度,各种项目开始从规划阶段进入实际执行。对于实习生来说,这个时间点进入团队,既赶上了业务最忙碌的窗口…

2026/10/13 14:21:17 阅读更多 →
Tableau标靶图实战:从坐标重构到业务决策穿透

Tableau标靶图实战:从坐标重构到业务决策穿透

1. 标靶图不是炫技,是业务问题的视觉翻译器“手把手教你 Tableau 绘制标靶图(十)”——这个标题里藏着一个被很多人忽略的关键信号:它不是第1次讲,而是第10次。这意味着标靶图在真实业务场景中已被反复验证、持续迭代&…

2026/10/13 14:21:17 阅读更多 →
JVMTI Agent开发避坑指南:从加载失败到生产级稳定

JVMTI Agent开发避坑指南:从加载失败到生产级稳定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:20:16 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →