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

TypeScript 基础与类型系统详解:从入门到实践

TypeScript 作为 JavaScript 的超集,凭借其强大的类型系统逐渐成为前端开发的主流选择。本文将基于 TypeScript 的核心特性,从基础概念到实际应用,带您全面掌握 TypeScript 的类型系统。

一、TypeScript 是什么?

TypeScript 是 JavaScript 的超集,它在 JavaScript 的基础上添加了类型系统和对 ES6 + 特性的支持,由 Microsoft 开发和维护,且是开源的编程语言。与 JavaScript 不同的是,TypeScript 最终会被编译成 JavaScript 代码,因此可以在任何支持 JavaScript 的平台上运行。

为什么需要为 JavaScript 添加类型支持?这源于 JavaScript 类型系统的 "先天缺陷"——JS 代码中绝大部分错误都是类型错误(Uncaught TypeError),这会增加找 Bug、改 Bug 的时间,严重影响开发效率。

从编程语言的动静区分来看,TypeScript 属于静态类型语言,而 JavaScript 属于动态类型语言:

  • 静态类型:在编译期做类型检查
  • 动态类型:在执行期做类型检查

这种差异直接影响错误发现的时机:JavaScript 需要等到代码执行时才能发现错误,而 TypeScript 在编译阶段(甚至编写代码时,配合 PyCharm 等开发工具)就能发现错误,大幅减少调试时间。

二、TypeScript 的核心优势

TypeScript 相比 JavaScript,有以下关键优势:

  1. 静态类型检查:在编译阶段就能发现潜在错误,避免代码上线后出现类型相关的运行时错误。

  2. 更好的 IDE 支持:提供智能提示和代码补全,大幅提升开发效率。例如在编写对象属性时,IDE 能自动提示该对象包含的属性,减少拼写错误。

  3. 更好的代码组织:支持面向对象编程,通过接口、类等特性让代码结构更清晰,便于大型项目维护。

  4. 支持最新 JavaScript 特性:可以提前使用 ES6 + 的新特性,通过编译兼容旧版本浏览器。

  5. 提高代码可维护性和可读性:类型注解让代码的意图更明确,新接手项目的开发者能更快理解代码逻辑。

三、TypeScript 环境搭建

在环境搭建之前首先带大家先了解一下TypeScript的基本执行流程:

基本执行流程:

 详细执行流程:

从上图的执行流程可以看出来ts不能直接运行,需要现将ts转换为js才能运行。typescript 包:用来编译 TS 代码的包,提供了 tsc 命令,实现了 TS -> JS 的转化。

使用 TypeScript 前,需完成环境搭建,步骤如下:
1. 安装 TypeScript:通过 npm 安装:

全局安装:npm install -g typescript
局部安装:npm install typescript --save-dev

检查TypeScript是否安装成功:

tsc -v

2. 简化运行流程每次修改后编译再执行过于繁琐,可使用ts-node直接运行 TS 文件

npm i -g ts-node  # 安装(ts-node包中有ts-node语句)
ts-node 文件名称 # 直接运行TS文件(内部自动完成编译)

3. 自动监听流程:上述的方法中,每次修改代码后都需要重写运行的时候都需要重新编译,那么怎么实现修改ts代码的时候js也在同步发生改变,以下就是实现该功能的相关描述:

tsc --init  //初始化配置json
tsc --watch //监听文件变化

四、TypeScript 基本类型系统

TypeScript 提供了丰富的基本类型,用于在编译时进行类型检查,以下是常用类型及示例:

4.1 基础原始类型

  • 布尔值(boolean):表示逻辑值truefalse

let isDone: boolean = false;
isDone = true;
  • 数字(number):支持整数、浮点数及二进制、八进制、十六进制

let decimal: number = 6;
let hex: number = 0xf00d;   // 十六进制
let binary: number = 0b1010;  // 二进制
  • 字符串(string):支持单引号、双引号及模板字符串

let color: string = "blue";
let fullName: string = `Bob Bobbington`;
let sentence: string = `Hello, my name is ${fullName}.`; // 模板字符串

4.2 复合类型

  • 数组(Array):两种定义方式:元素类型后加[]或泛型Array<元素类型>

let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3]; // 泛型语法
  • 元组(Tuple):已知元素数量和类型的数组,各元素类型可不同

let x: [string, number]; // 第一个元素为string,第二个为number
x = ["hello", 10]; //  正确
// x = [10, "hello"]; // 错误,类型顺序不匹配
  • 枚举(enum):命名的数字常量集合,增强可读性

// 默认从0开始编号
enum Color {Red,Green,Blue
}
let c: Color = Color.Green;   // 值为1
// 也可手动赋值
enum Status {Success = 200,NotFound = 404
}

4.3 特殊类型

  • any 类型:允许任何类型的值,会跳过类型检查,应谨慎使用

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
  • void 类型:表示没有返回值的函数或变量(只能赋值为undefinednull

function sayHello(): void {console.log("Hello");  // 无返回值
}
  • null 和 undefined:所有类型的子类型(除非启用strictNullChecks

let u: undefined = undefined;
let n: null = null;
  • never 类型:表示永远不会返回的值,如抛出异常或无限循环的函数

function error(message: string): never {throw new Error(message);
}
  • object 类型:非原始类型(即不是 number、string、boolean 等)

let obj: object = {name: "Bob",age: 20,sex:"男"
}

五、类型注解与类型推断

TypeScript 的类型系统有两种工作方式:类型注解(显式指定)和类型推断(自动识别)。

5.1 类型注解(Type Annotations)

开发者显式指定变量、函数参数或返回值的类型,增强代码可读性,明确表达意图。

示例:

// 变量类型注解
let age: number = 25;// 函数参数和返回值类型注解
function greet(name: string): string {return `Hello, ${name}`;
}console.log(greet("John"));

运行结果:


 

5.2 类型推断(Type Inference)

当没有显式标注类型时,TypeScript 编译器会根据变量的初始值自动推断类型,减少冗余代码,提升开发效率。

示例:

let message = "Hello TypeScript";  // 推断为string类型
let count = 10;  // 推断为number类型

推断结果:

 注意:如果变量未被初始化或赋值不明确,TypeScript 可能会推断为any类型(取决于是否启用严格模式)。

5.3 上下文类型推断(Contextual Typing)

根据变量使用的上下文推断类型,常见于函数参数、回调等场景。

示例:

window.addEventListener("click", (event) => {console.log(event);  // TypeScript自动推断event是MouseEvent类型
});

推断结果:

5.4 最佳实践

  • 显式类型注解适用于 API 设计、公共函数签名等关键位置
  • 类型推断适用于局部变量、简单逻辑中,保持代码简洁
  • 合理结合两者,既保证类型安全,又提高开发效率

六、联合类型与类型断言以及类型守卫

在处理不确定类型的值时,联合类型和类型断言是常用的工具。

6.1 联合类型(Union Types)

使用|表示一个变量可以是多个类型中的一种,常用于处理不确定类型的值(如 API 返回、用户输入等)。

示例:

let value: string | number;   // 规定value只能是string或number类型
value = "hello";  // 合法
value = 42;  // 合法
value = true;  // 错误,不是string或number类型

 运行结果:

6.2 类型断言(Type Assertion)

类型断言(Type Assertion)在 TypeScript 中的作用是告诉编译器:“我比你更了解这个变量的类型”。它允许你手动指定一个值的类型,从而绕过 TypeScript 的类型检查。

两种语法:

// 方式1:as语法(推荐)
let someValue: any = true;
let strLength1: number = (someValue as string).length;
console.log(strLength1)
// 方式2:尖括号语法
let strLength2: number = (<string>someValue).length;

主要作用包括
---访问特定属性或方法:当你确定某个值的具体类型时,可以使用类型断言来访问该类型的特定属性或方法。
---处理 DOM 元素:例如通过 document.getElementById 获取的元素可能是 HTMLElement 类型,但你知道它是 HTMLInputElement,就可以使用类型断言。
---解决联合类型问题:当你希望将联合类型 (A | B) 视为其中某一个具体类型时。

const el = document.getElementById('myInput') as HTMLInputElement;
el.value = 'hello'; // 现在可以安全访问 value 属性

6.3 类型守卫(Type Guards)

通过条件语句进一步缩小类型范围,实现类型的安全访问,是 TypeScript 实现类型收窄的核心机制。

常见类型守卫方式:

1. typeof 检查(适用于原始类型)

function padLeft(value: string | number): string {if (typeof value === "number") {return " ".repeat(value);  // 此处确定value是number类型}return value;  // 此处确定value是string类型
}

2. instanceof 检查(适用于类实例)

if (error instanceof Error) {console.error(error.message);  // 确定error是Error实例
}

3. 自定义类型守卫函数

// value: string | number:参数可以是 string 或 number 类型。
// value is string:这是一个类型谓词(type predicate),告诉 TypeScript,
// 如果函数返回 true,则 value 是 string 类型。
function isString(value: string | number): value is string {return typeof value === "string";
}let value: string | number = "hello";
// 使用
if (isString(value)) {console.log(value.toUpperCase());  // 确定value是string类型
}

4. in 操作符判断对象属性

type Dog = { bark: () => void };
type Cat = { meow: () => void };function makeSound(animal: Dog | Cat): void {if ("bark" in animal) {animal.bark();  // 确定是Dog类型} else {animal.meow();  // 确定是Cat类型}
}

七、实际案例:Hello World 与类型实践

7.1 第一个 TypeScript 程序

// hello.ts
function greet(name: string): string {return `Hello, ${name}!`;
}const userName: string = "TypeScript";
console.log(greet(userName));  // 输出:Hello, TypeScript!

7.2 联合类型与类型守卫综合案例

实现一个函数,根据输入类型返回不同结果:

function processValue(value: string | number | boolean): any {if (typeof value === "string") {return value.length;  // 字符串:返回长度} else if (typeof value === "number") {return value **2;  // 数字:返回平方} else {return !value;  // 布尔值:返回反值}
}console.log(processValue("hello"));  // 5
console.log(processValue(5));  // 25
console.log(processValue(true));  // false

八、总结

TypeScript 通过引入静态类型系统,解决了 JavaScript 在大型项目开发中的类型安全问题。其核心优势在于编译期的类型检查、更好的开发工具支持以及代码可维护性的提升。

掌握 TypeScript 的类型系统(基本类型、联合类型等)、类型注解与推断机制,以及类型守卫的使用,能帮助我们编写更健壮、更易维护的代码。合理利用 TypeScript 的特性,既能保证类型安全,又能提高开发效率,是现代前端开发的重要技能。

无论是小型应用还是大型项目,TypeScript 都能为代码质量保驾护航,值得每一位 JavaScript 开发者深入学习和实践。

http://www.lryc.cn/news/582012.html

相关文章:

  • TB62216FTG,TB62216FNG东芝BiCD集成电路硅单片,PWM斩波型电机驱动集成电路
  • 【Chrome】‘Good助手‘ 扩展程序使用介绍
  • 【操作系统】页面置换
  • OpenWebUI(2)源码学习-后端retrieval检索模块
  • vulnhub靶机渗透:PWNLAB: INIT
  • 海外短剧系统开发:PC端与H5端的全栈实践与深度解析
  • Java-66 深入浅出 分布式服务 Netty详解 EventLoop
  • [特殊字符] Excel 读取收件人 + Outlook 批量发送带附件邮件 —— Python 自动化实战
  • 嵌入式硬件中电容的基本原理与实现详解02
  • Excel 的多线程特性
  • 线程安全的单例模式与读者写者问题
  • WebRTC与RTMP
  • GPT5完全多模态架构拆解:实时视频生成如何颠覆内容创作
  • 什么是去中心化 AI?区块链驱动智能的初学者指南
  • 【C++指南】STL queue 完全解读(一):原理剖析与实战应用
  • 开源鸿蒙(OpenHarmony)桌面版全面解析:架构适配、设备支持与开发实战
  • Matlab自学笔记六十二:求解三角函数方程的通解周期解
  • 【JAVAFX】webview导入本地html并传入参数
  • 【论文笔记】World Models for Autonomous Driving: An Initial Survey
  • excel日志表介绍
  • C++学习笔记01(自学草稿)
  • 国民经济行业分类 GB/T 4754—2017 (PDF和exce版本)
  • 中电金信 :十问高质量数据集:金融大模型价值重塑有“据”可循
  • 【Unity笔记】Unity 粒子系统 Triggers 使用解析:监听粒子进入与离开区域并触发事件
  • maven 发布到中央仓库常用脚本-02
  • .NET9 实现 JSON 序列化和反序列化(Newtonsoft.Json System.Text.Json)性能测试
  • ArcGIS 水文分析升级:基于深度学习的流域洪水演进过程模拟
  • 3S技术+ArcGIS/ENVI全流程实战:水文、气象、灾害、生态、环境及卫生等领域应用
  • 语音交互新纪元:Hugging Face LeRobot如何让机器人真正“懂你”
  • validate CRI v1 image API for endpoint “unix:///run/containerd/containerd.sock“