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

TypeScript 入门基础:与原生 JavaScript 的详细对比

TypeScript 入门基础与原生 JavaScript 的详细对比前言TypeScript 是由微软开发并维护的开源编程语言它是 JavaScript 的一个超集。这意味着所有合法的 JavaScript 代码同时也是合法的 TypeScript 代码。TypeScript 在 JavaScript 的基础上添加了可选的静态类型检查让我们在开发阶段就能发现大量潜在错误并获得更强大的编辑器智能提示与重构能力。本文将带你从零开始学习 TypeScript 的核心基础并在每个概念上对比原生 JavaScript帮助你更直观地理解 TS 带来的价值。1. 环境搭建与编译JavaScript 的运行方式原生 JS 可以直接在浏览器或 Node.js 中运行无需任何编译过程。你写好一个.js文件直接用 Node 执行或引入 HTML 即可。TypeScript 需要编译TypeScript 代码不能直接在浏览器或 Node.js 中运行需要先通过TypeScript 编译器 (tsc)将其转换成 JS 代码。安装 TypeScriptnpminstall-gtypescript编写一个简单的hello.tsfunctiongreet(name:string):string{returnHello,${name};}console.log(greet(World));编译并运行tsc hello.ts# 生成 hello.jsnodehello.js# 输出: Hello, Worldtsconfig.json 配置文件实际项目中我们通过tsconfig.json精细控制编译行为{compilerOptions:{target:ES2020,// 编译目标 JS 版本module:commonjs,// 模块系统strict:true,// 开启所有严格类型检查outDir:./dist,rootDir:./src}}之后只需执行tsc即可编译整个项目。对比总结JS 零配置直接运行开发轻快但缺乏编译时检查。TS 增加了编译环节但换来的是类型安全和更早的错误发现。2. 类型注解与类型推断JavaScript 是一门动态类型语言// JS: 变量可以随时赋值为任意类型letmessageHello;message42;// 完全合法但可能引发运行时 BUGTypeScript 允许我们为变量添加类型注解// TS: 指定类型后赋值其他类型会编译报错letmessage:stringHello;message42;// ❌ 错误: 不能将类型“number”分配给类型“string”。基本类型TS 支持所有 JS 原始类型并额外增加了一些类型说明示例string字符串let name: string Alice;number数字let age: number 30;boolean布尔值let done: boolean false;array数组let list: number[] [1,2,3];tuple固定长度、类型的元组let x: [string, number];enum枚举(后面详谈)any任意类型跳过检查let data: any 5;void无返回值函数function log(): void {}null/undefined与 strictNullChecks 相关never永远不存在的值的类型函数抛出异常或死循环object非原始类型let obj: object {};类型推断TS 很智能能自动推断变量的类型不必处处标注letgreetingHi;// 推断为 stringgreeting100;// ❌ 报错因为已经被推断为 string这种情况与显式注解let greeting: string Hi等价。联合类型与类型别名在 JS 中一个函数参数既可以接收字符串也可以接收数字通常只能在代码内判断// JS: 运行时判断functionprintId(id){if(typeofidstring)console.log(id.toUpperCase());elseconsole.log(id);}TS 可以使用联合类型清晰表达typeIDstring|number;// 类型别名functionprintId(id:ID):void{if(typeofidstring){console.log(id.toUpperCase());}else{console.log(id);}}string | number表示既可以是 string 也可以是 number编辑器会根据类型缩小Narrowing提供准确的提示。对比总结JS 的类型信息存在于运行时和开发者的脑海中容易遗忘导致类型错误。TS 的类型注解和推断将类型信息写入代码成为“活文档”在编码阶段就杜绝了类型不匹配的错误。3. 接口InterfaceJavaScript 对象是无固定形状的函数只能靠文档或运行时的typeof去保证参数结构// JS: 期望 user 有 name 和 age 属性但没有任何强制functiongetUserInfo(user){return${user.name}is${user.age}years old;}getUserInfo({name:Bob});// 运行时访问 undefined可能造成 bugTypeScript 使用接口来定义对象的结构interfaceUser{name:string;age:number;}functiongetUserInfo(user:User):string{return${user.name}is${user.age}years old;}getUserInfo({name:Bob});// ❌ 编译错误缺少 age 属性接口的高级特性可选属性age?: number只读属性readonly id: number函数类型接口interfaceSearchFunc{(source:string,subString:string):boolean;}可索引类型[index: number]: string接口继承interfaceAdminextendsUser{role:string;}类实现接口classPersonimplementsUser{name:string;age:number;constructor(name:string,age:number){this.namename;this.ageage;}}对比总结JS 中对象的结构约束全靠约定和运行时检查代码编写者需要自己保证一致性。TS 的接口在编译阶段强制检查对象形状让代码更加自文档化也让重构变得更加安全和容易。4. 类ClassES6 为 JS 引入了类语法但缺少访问控制符如private和抽象类等特性// JS (ES6)classAnimal{constructor(name){this.namename;// 没有私有化机制约定用 _name 表示私有}speak(){console.log(${this.name}makes a noise.);}}TypeScript 提供了完整的面向对象增强访问修饰符public默认可自由访问private只能在类内部访问protected能在类及子类中访问classAnimal{privatename:string;// 私有属性constructor(name:string){this.namename;}publicspeak():void{console.log(${this.name}makes a noise.);}}constdognewAnimal(Dog);dog.name;// ❌ 错误: 属性“name”为私有属性只能在类“Animal”中访问。参数属性TS 允许在构造函数参数中直接声明并初始化成员简化代码classAnimal{constructor(privatename:string){}// 等价于声明了一个 private name 并在构造函数中赋值}抽象类不能直接实例化的类用于定义公共行为并由子类实现abstractclassAnimal{abstractmakeSound():void;// 抽象方法子类必须实现move():void{console.log(moving...);}}classDogextendsAnimal{makeSound(){console.log(Woof!);}}与 JS 私有字段 (#) 对比ES2022 引入了真正的私有字段#name但 TS 的private只在编译时检查编译到 JS 后依然可访问除非目标 ES2022 并使用#。通常 TS 项目中更常用private修饰符。对比总结JS 的类更简单缺少访问控制和抽象机制大型项目维护时容易误操作对象内部状态。TS 的类通过访问修饰符和抽象类提供了更严谨的 OOP 设计提高封装性和代码的可维护性。5. 函数JavaScript 函数参数无类型约束重载需要手动处理// JS: 模拟重载functionadd(a,b){if(typeofanumbertypeofbnumber){returnab;}if(typeofastringtypeofbstring){returna.concat(b);}}TypeScript 函数可以定义参数和返回值的类型还支持函数重载基本类型声明functionadd(a:number,b:number):number;functionadd(a:string,b:string):string;functionadd(a:any,b:any):any{returnab;}add(1,2);// 3add(a,b);// abadd(1,b);// ❌ 报错没有与此调用匹配的重载重载签名列表 一个实现函数外部调用时只能使用已定义的重载签名保证了类型安全。可选参数和默认参数functionbuildName(firstName:string,lastName?:string):string{if(lastName)return${firstName}${lastName};returnfirstName;}// 或直接默认值lastName: string Smith剩余参数functionsum(...numbers:number[]):number{returnnumbers.reduce((acc,cur)acccur,0);}对比总结JS 中函数参数数量和类型完全由调用方决定类型错误要到运行时才暴露。TS 通过类型注解、重载声明使得函数调用契约一目了然编译器会帮你检查传入的参数。6. 泛型Generics在 JavaScript 中要想写一个能返回任意类型输入的函数只能使用any或放弃类型// JS: 丢失了类型信息functionidentity(arg){returnarg;}letoutputidentity(hello);// output 是 any没有类型提示TypeScript 的泛型允许我们在定义时使用类型变量调用时才确定具体类型functionidentityT(arg:T):T{returnarg;}letoutput1identitystring(hello);// output1 明确为 stringletoutput2identity(42);// 类型推断为 number泛型不仅适用于函数还可以用于接口和类interfaceGenericRepositoryT{getById(id:number):T;getAll():T[];}classUserRepositoryimplementsGenericRepositoryUser{getById(id:number):User{/* ... */}getAll():User[]{/* ... */}}泛型约束可以限制泛型必须具有某些属性interfaceLengthwise{length:number;}functionlogLengthTextendsLengthwise(arg:T):T{console.log(arg.length);returnarg;}logLength(hello);// OKlogLength(123);// ❌ number 没有 length 属性对比总结JS 无法表达“某个函数可以处理任意类型但要保持类型关系”只能依赖any和手动类型判断。TS 的泛型让我们写出既灵活又类型安全的代码并且不丢失类型信息编辑器能够给出准确提示。7. 枚举EnumJavaScript 没有枚举类型通常使用常量或对象模拟// JS 模拟枚举constDirection{Up:0,Down:1,Left:2,Right:3};这种方式没有类型约束任意数字都能赋值容易出错。TypeScript 内置枚举enumDirection{Up,// 默认 0Down,// 1Left,// 2Right// 3}functionmove(dir:Direction):void{// ...}move(Direction.Up);// OKmove(5);// ❌ 错误类型“5”的参数不能赋给“Direction”字符串枚举enumStatus{ActiveACTIVE,InactiveINACTIVE}常量枚举用const enum定义编译时直接内联值不生成额外的对象代码constenumColor{Red,Green,Blue}letcColor.Red;// 编译后变成 let c 0;对比总结JS 中模拟枚举容易导致误用且缺乏命名空间的聚合感。TS 枚举提供了有名字的常量集合使得代码可读性更强同时受类型系统的约束避免无效值。8. 高级类型与工具类型概览随着应用规模扩大你还会接触到更强大的类型工具这些都是 JavaScript 完全不具备的交叉类型A B同时满足多个类型类型守卫typeof、instanceof、自定义判断帮助类型缩小类型断言as告诉编译器“我知道这是什么类型”非空断言!排除null/undefined工具类型TypeScript 内置PartialT、RequiredT、ReadonlyT、PickT, K、OmitT, K等快速基于已有类型创建新类型。interfaceTodo{title:string;description:string;completed:boolean;}typeTodoPreviewPickTodo,title|completed;// { title: string; completed: boolean }这些特性在 JS 中只能靠人工保证无法在编码阶段自动化验证。9. 模块与命名空间ES6 提供了标准的模块系统import/exportTypeScript 完全兼容并扩展了类型导出。// user.tsexportinterfaceUser{name:string;age:number;}exportfunctioncreateUser(name:string,age:number):User{return{name,age};}// main.tsimport{User,createUser}from./user;constuser:UsercreateUser(Alice,30);TS 还保留了“命名空间”内部模块的概念用于组织代码避免全局污染namespaceUtils{exportfunctionlog(msg:string):void{console.log(msg);}}Utils.log(Hi);不过现代项目更推荐使用 ES 模块。对比总结JS 使用 ES 模块导入导出的是值没有类型概念。TS 的模块可以导入导出类型interface、type等这些在编译后会被完全擦除只影响编译阶段让跨文件的类型检查成为可能。10. TypeScript 与 JavaScript 的互操作实际项目中我们常常需要与纯 JS 代码或第三方库协作。TS 为此提供了多种手段声明文件.d.ts为 JS 库提供类型描述例如jquery.d.ts。社区维护的 DefinitelyTyped 提供了海量types包安装即可npm install --save-dev types/lodash。any和unknown当无法确定类型时any完全跳过检查unknown要求使用前做类型判断更安全。类型断言const el document.getElementById(app) as HTMLDivElement;非空断言user!.name告诉编译器user一定不为null/undefined。从 JS 迁移到 TS可以渐进式进行将.js重命名为.ts逐步添加类型注解开启strict模式将不安全的代码暴露出来并修复。对比总结JS 生态的海量库可以直接在 TS 中使用TS 通过声明文件赋予了类型智能而 JS 调用这些库时依然缺乏类型保障。结语TypeScript 并不是要替代 JavaScript而是给 JavaScript 插上了“类型之翼”。它让我们在开发大型应用时能够在编码阶段避免常见的类型错误获得精确的智能提示和重构能力写出自解释、可维护的代码JavaScript 的灵活性依然在但 TypeScript 让这种灵活性被约束在一个安全的边界内。正如前端框架之于原生 DOMTypeScript 之于 JavaScript 也是开发效率的巨大提升。如果你已经掌握了 JavaScript那么学习 TypeScript 的成本并不高——它只是 JS 的**“类型注释版”**。希望本文的对比讲解能帮你迈出坚实的第一步快速将 TS 应用到你的项目中。
http://www.gsyq.cn/news/1346910.html

相关文章:

  • NotebookLM提示工程进阶指南,深度拆解98%用户忽略的3层语义对齐机制
  • 5分钟掌握Mermaid Live Editor:免费在线图表编辑的终极解决方案
  • 3分钟快速掌握Cursor试用重置工具:一键解除AI编程助手限制的完整指南
  • 博德之门3模组管理艺术:从混乱到有序的终极掌控指南
  • 辽宁寄快递哪家最便宜?4 个全国靠谱低价寄件平台推荐 - 时讯资讯
  • 如何快速完成北航毕业论文:LaTeX模板终极指南
  • 5分钟掌握Subfinder:自动化字幕下载的终极解决方案
  • 性价比高的张家港空压机哪个公司好 - 速递信息
  • 2026企业微信SCRM价格对比:不同预算怎么选?
  • 为了还原具身智能科研市场的全貌,我们找了多个头部高校聊聊
  • Mac Mouse Fix完整指南:如何让普通鼠标在macOS上超越触控板体验
  • 2026上海英国留学申请、费用、机构选择全维度攻略 - 行情观察室
  • 2026 年昆山装修公司排名前十强推荐 靠谱家装公司口碑与实力榜单 - 速递信息
  • 2026 年国内格栅、化粪池、盖板优质企业推荐榜 - 深度智识库
  • Windows Server TLS安全加固:注册表三步禁用Sweet32漏洞
  • 无需复杂代理快速为你的项目接入GPT4与Claude等多模型
  • 3分钟搞定Figma中文界面:FigmaCN汉化插件完整指南
  • Unity C#中List.Find性能陷阱与优化实践
  • Unity数字人口型同步:音素驱动的实时语义对齐方案
  • 新手入门教程使用Python快速配置Taotoken的OpenAI兼容API调用环境
  • 石家庄周边一日游 石家庄附近一日游 哪个旅行社发一日游线路 - 好物推荐官
  • ML部署自动化:自动化机器学习模型部署流程
  • CVE漏洞验证闭环:从查询到实测的工程化实践
  • 悦刻母公司雾芯季报图解:营收15.9亿 靠卖电子烟净利3亿
  • 英伟达季报图解:营收817亿同比增85% 净利583亿美元 黄仁勋称Agentic AI时代到来
  • KMS_VL_ALL_AIO:Windows和Office一键智能激活解决方案
  • 设计程序统计商务回访频次,客户复购数据,确定标准回访周期,稳固企业长期商务客户资源。
  • UniversalUnityDemosaics:Unity游戏视觉体验完整恢复终极指南
  • 企业数据集成难题:如何用Pentaho Kettle 11.0轻松实现ETL自动化
  • 告别百度文库付费墙:一个JavaScript脚本如何帮你免费获取纯净文档