news 2026/6/25 18:57:21

19-TypeScript 基础集成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
19-TypeScript 基础集成

TypeScript 基础集成

从 JavaScript 到 TypeScript:用静态类型提升代码质量与开发体验


学习目标

读完本文,你将学会:

  • 理解 TypeScript 的类型系统和编译原理
  • 掌握常用类型注解和接口定义
  • 使用泛型编写可复用的类型安全代码
  • 在现有 JavaScript 项目中渐进式引入 TypeScript

一、为什么要用 TypeScript

1.1 JavaScript 的类型问题

// 运行时才发现错误functionadd(a,b){returna+b;}add(1,2);// 3 ✅add('1','2');// '12' ❌ 逻辑错误,但语法合法add(1,'2');// '12' ❌ 更隐蔽的问题// 属性拼写错误constuser={name:'Alice'};console.log(user.nmae);// undefined,不报错

1.2 TypeScript 的价值

JavaScript TypeScript ↓ ↓ 动态类型 静态类型检查 运行时错误 编译时捕获错误 IDE 提示弱 智能补全和重构 文档靠注释 类型即文档 重构风险高 安全重构

1.3 TS 编译流程

TypeScript 源码 ↓ tsc 编译器 ↓ 类型检查 + 语法转换 ↓ JavaScript 目标代码(ES5/ES6/ESNext) ↓ 浏览器 / Node.js 运行

二、基础类型

2.1 基本类型注解

// 原始类型letname:string='Alice';letage:number=25;letisActive:boolean=true;letempty:null=null;letnotDefined:undefined=undefined;// 任意类型(尽量少用)letanything:any=4;anything='string';anything=true;// 未知类型(类型安全的 any)letunknownValue:unknown=4;// unknownValue.toFixed(); // ❌ 错误:先需要类型断言或类型守卫if(typeofunknownValue==='number'){unknownValue.toFixed();// ✅}// 无返回值functionlogMessage(msg:string):void{console.log(msg);}// 永不返回functionthrowError(msg:string):never{thrownewError(msg);}

2.2 数组与元组

// 数组letnumbers:number[]=[1,2,3];letnames:Array<string>=['Alice','Bob'];// 元组(固定长度和类型)letpoint:[number,number]=[10,20];letuserInfo:[string,number,boolean]=['Alice',25,true];// 只读数组constreadonlyArr:readonlynumber[]=[1,2,3];// readonlyArr.push(4); // ❌ 错误

2.3 对象与接口

// 接口定义interfaceUser{id:number;name:string;email:string;age?:number;// 可选属性readonlycreatedAt:Date;// 只读属性}constuser:User={id:1,name:'Alice',email:'alice@example.com',createdAt:newDate()};// 索引签名interfaceDictionary{[key:string]:string;}constcolors:Dictionary={red:'#ff0000',green:'#00ff00'};// 类型别名typePoint={x:number;y:number};typeID=string|number;typeCallback=(data:string)=>void;

三、联合类型与类型守卫

3.1 联合类型

functionformatInput(input:string|number):string{// 类型守卫if(typeofinput==='string'){returninput.trim();// TS 知道这里是 string}returninput.toFixed(2);// TS 知道这里是 number}

3.2 类型收窄

interfaceBird{type:'bird';fly():void;}interfaceFish{type:'fish';swim():void;}typeAnimal=Bird|Fish;functionmove(animal:Animal){// 可辨识联合switch(animal.type){case'bird':animal.fly();// TS 知道是 Birdbreak;case'fish':animal.swim();// TS 知道是 Fishbreak;default:const_exhaustive:never=animal;// 穷尽检查}}

四、泛型

4.1 基础泛型

// 泛型函数functionidentity<T>(value:T):T{returnvalue;}constnum=identity<number>(42);// numberconststr=identity('hello');// 类型推断为 string// 泛型接口interfaceContainer<T>{value:T;getValue():T;}constnumberBox:Container<number>={value:100,getValue(){returnthis.value;}};

4.2 泛型约束

interfaceHasLength{length:number;}functionlogLength<TextendsHasLength>(arg:T):T{console.log(arg.length);returnarg;}logLength('hello');// ✅ string 有 lengthlogLength([1,2,3]);// ✅ 数组有 length// logLength(123); // ❌ number 没有 length

4.3 泛型工具类型

// Partial: 所有属性可选interfaceUser{id:number;name:string;}typePartialUser=Partial<User>;// { id?: number; name?: string; }// Pick: 选取部分属性typeUserName=Pick<User,'name'>;// { name: string; }// Omit: 排除部分属性typeUserWithoutId=Omit<User,'id'>;// { name: string; }// Record: 键值对对象typePageInfo=Record<string,{title:string;path:string}>;// ReturnType: 提取函数返回类型functioncreateUser(){return{id:1,name:'Alice'};}typeNewUser=ReturnType<typeofcreateUser>;// Parameters: 提取函数参数类型typeCreateUserParams=Parameters<typeofcreateUser>;

五、类与面向对象

interfaceAnimal{name:string;makeSound():void;}classDogimplementsAnimal{name:string;privateage:number;// 私有属性protectedbreed:string;// 受保护属性constructor(name:string,age:number,breed:string){this.name=name;this.age=age;this.breed=breed;}makeSound():void{console.log(`${this.name}says: Woof!`);}// GettergetisAdult():boolean{returnthis.age>=2;}// 静态方法staticcreatePuppy(name:string):Dog{returnnewDog(name,0,'Unknown');}}constdog=newDog('Buddy',3,'Golden Retriever');dog.makeSound();console.log(dog.isAdult);// true// console.log(dog.age); // ❌ 私有属性不可访问

六、在 JS 项目中渐进式引入 TS

6.1 步骤

# 1. 安装 TypeScriptnpminstall--save-dev typescript# 2. 初始化配置npx tsc--init# 3. 重命名文件 .js → .ts(或保留 .js,添加 JSDoc 类型注释)# 4. 配置 tsconfig.json
// tsconfig.json{"compilerOptions":{"target":"ES2020","module":"ESNext","moduleResolution":"node","strict":true,"esModuleInterop":true,"skipLibCheck":true,"forceConsistentCasingInFileNames":true,"outDir":"./dist","rootDir":"./src","declaration":true,"declarationMap":true,"sourceMap":true},"include":["src/**/*"],"exclude":["node_modules","dist","**/*.test.ts"]}

6.2 JSDoc 类型注释(不修改 .js 文件)

/** * @param {string} name * @param {number} age * @returns {string} */functiongreet(name,age){return`Hello${name}, you are${age}`;}/** @type {import('./types').User} */constuser={id:1,name:'Alice'};

二、常见误区与注意点

误区正确做法
TypeScript 在运行时做类型检查TS 类型只在编译时检查,运行时无类型信息
any 可以随便用尽量不用 any,使用 unknown + 类型守卫
接口和类型别名完全等价接口可声明合并,类型别名更灵活
泛型越复杂越好泛型应服务于复用,避免过度抽象
一次性全量迁移到 TS渐进式迁移,从核心模块开始

三、动手练习

练习 1:为 API 响应定义类型

为一组 REST API 接口定义请求参数和响应数据的 TypeScript 类型。

练习 2:实现泛型工具函数

实现一个deepClone泛型函数,支持深拷贝任意对象。


四、AI 辅助学习

4.1 本节知识点的 AI 提问模板

  • “TypeScript 的 interface 和 type 有什么区别?”
  • “如何实现一个类型安全的 EventEmitter?”
  • “unknown 和 any 的区别是什么?”

4.2 警惕 AI 的常见错误

  • AI 可能生成运行时依赖类型信息的代码(如typeof variable === 'User'
  • AI 可能忘记 TS 类型擦除特性

五、配套代码

本文示例代码位于:CODE-ADVANCED/19-TypeScript基础集成/

文件名说明
ts-basic.ts基础类型、接口、类型守卫
ts-advanced.ts泛型、工具类型、类与面向对象
ts-config-demo.jsontsconfig.json 推荐配置

六、本章小结

  • TypeScript 在编译时进行类型检查,捕获潜在错误
  • 接口、类型别名、联合类型构建类型系统基础
  • 泛型让代码在保证类型安全的同时保持复用性
  • 现有 JS 项目可通过渐进式迁移引入 TS

如果本文对你有帮助,欢迎点赞、收藏、关注专栏。有任何问题可以在评论区交流!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/25 18:55:05

Netflix推荐系统背后的用户体验工程实践

1. 这不是“推荐算法”四个字能概括的真相你点开Netflix首页&#xff0c;一排排剧集自动滑过&#xff0c;封面图精准得像懂你心——《黑镜》刚刷完&#xff0c;《西部世界》就跳出来&#xff1b;孩子刚看完《蓝色海底小纵队》&#xff0c;下一秒“儿童推荐区”就堆满海洋主题动…

作者头像 李华
网站建设 2026/6/25 18:45:13

【2013-10-29】Android应用开发笔记:全屏和去除标题栏

[历史归档] 本文原发布于 cstriker1407.info 个人博客&#xff0c;内容为历史存档&#xff0c;仅供参考。 发布时间&#xff1a; 2013-10-29 &#xff5c; 标题&#xff1a;Android应用开发笔记&#xff1a;全屏和去除标题栏 &#xff5c; 分类&#xff1a; 编程 / android…

作者头像 李华
网站建设 2026/6/25 18:42:16

T-PAW攻击:矿池算力时间博弈与防御策略

1. 项目概述&#xff1a;当“临时算力”成为攻击武器在区块链的世界里&#xff0c;矿池是算力的集散地&#xff0c;也是整个网络安全与效率的基石。我们通常认为&#xff0c;矿工向矿池贡献算力&#xff0c;矿池则负责打包交易、分配收益&#xff0c;这是一个稳定且互惠的协作模…

作者头像 李华
网站建设 2026/6/25 18:40:08

Hotkey Detective:Windows热键冲突终极解决方案完全指南

Hotkey Detective&#xff1a;Windows热键冲突终极解决方案完全指南 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 你是否…

作者头像 李华
网站建设 2026/6/25 18:36:00

自媒体选词误区总结:避开泛流量,精准匹配用户需求

很多做自媒体的人都会遇到同一个问题&#xff0c;日常坚持更新作品&#xff0c;内容能拿到少量曝光和浏览&#xff0c;但精准受众特别少&#xff0c;几乎没有有效用户反馈。账号积累的大多是无用泛流量&#xff0c;会导致平台无法识别账号定位&#xff0c;推送流量越来越杂乱。…

作者头像 李华