TypeScript 简介
TypeScript 是由微软开发的一种编程语言,它是 JavaScript 的超集(TypeScript⊇JavaScript),于 2012 年首次发布。TypeScript 添加了静态类型和其他特性到 JavaScript 中,使得大型应用程序的开发更加容易和维护性更强。
TypeScript 的主要特点:
- 静态类型系统 - 允许在编码阶段捕获类型错误
- 面向对象编程 - 支持类、接口、继承等特性
- 现代 JavaScript 特性 - 支持最新的 ECMAScript 标准
- 更好的 IDE 支持 - 提供更精准的代码补全、重构和导航
- 编译时错误检查 - 在代码运行前发现潜在问题
JavaScript 与 TypeScript 的主要区别
让我通过一个表格和代码示例来展示它们的主要区别:
| 特性 | JavaScript | TypeScript |
|---|---|---|
| 类型系统 | 动态类型 | 静态类型(可选) |
| 编译 | 解释执行 | 编译为 JavaScript |
| 错误检测 | 运行时 | 编译时 + 运行时 |
| 代码补全 | 基础 | 更精准 |
| 学习曲线 | 较低 | 较陡峭 |
代码示例对比
JavaScript 示例:
javascript
function calculateTotal(price, quantity) {
return price * quantity;
}
// 调用函数
let total = calculateTotal(10, 5);
console.log(total); // 输出: 50
// 可能的错误 - JavaScript 不会报错
let wrongTotal = calculateTotal("10", "5");
console.log(wrongTotal); // 输出: "50" (字符串拼接)
TypeScript 示例:
TypeScript
function calculateTotal(price: number, quantity: number): number {
return price * quantity;
}
// 正确调用
let total: number = calculateTotal(10, 5);
console.log(total); // 输出: 50
// 错误调用 - TypeScript 会在编译时报错
// let wrongTotal = calculateTotal("10", "5");
// 错误: 类型"string"的参数不能赋给类型"number"的参数
主要差异详解
1.类型注解:
- JavaScript: 不需要显式声明类型
- TypeScript: 可以使用类型注解明确变量、函数参数和返回值的类型
2.接口定义:
- TypeScript 允许定义接口,强制对象结构符合特定形状
TypeScript
// TypeScript 接口示例
interface User {
id: number;
name: string;
email?: string; // 可选属性
}
function processUser(user: User) {
console.log(`Processing user: ${user.name}`);
}
// JavaScript 中没有这种强制结构的方式
3.枚举类型:
- TypeScript 提供枚举,JavaScript 没有原生枚举支持
TypeScript
// TypeScript 枚举示例
enum Color {
Red,
Green,
Blue
}
let favoriteColor: Color = Color.Blue;
4.泛型:
- TypeScript 支持泛型,使代码更加灵活和可重用
TypeScript
// TypeScript 泛型示例
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString");
5.访问修饰符:
- TypeScript 支持 public、private 和 protected 访问修饰符
TypeScript
class Person {
private name: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getInfo(): string {
return `${this.name} is ${this.age} years old`;
}
}
为什么要学习 TypeScript?
- 减少运行时错误:通过类型检查在开发阶段捕获更多错误
- 提高代码质量:类型系统使代码更加自文档化
- 更好的团队协作:明确的类型定义使团队成员更容易理解代码
- 强大的工具支持:提供更精确的自动补全、重构和导航功能
- 现代 JavaScript 特性:支持最新的 ECMAScript 特性,并可编译到旧版本
TypeScript 安装
在安装 TypeScript 之前,请确保您的系统已安装:
- Node.js(建议版本 14 或更高)
- npm(通常随 Node.js 一起安装)
方法一:全局安装(推荐初学者)
全局安装后,可以在任何项目中使用 TypeScript:
TypeScript
npm install -g typescript
安装完成后,检查版本:
TypeScript
tsc -v

方法二:项目级安装
在特定项目中安装 TypeScript:
TypeScript
# 初始化项目(如果还没有 package.json)
npm init -y
# 安装 TypeScript 作为开发依赖
npm install --save-dev typescript
使用项目级安装的 TypeScript:
TypeScript
# npx 命令会使用项目本地安装的版本
npx tsc -v
验证安装
创建一个简单的 TypeScript 文件来测试安装:
1.创建一个名为 test.ts 的文件:
TypeScript
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript"));
2.编译该文件:
tsc test.ts
3.运行生成的 JavaScript 文件:
node test.js
输出: Hello, TypeScript!

配置 TypeScript 项目
对于正式项目,建议创建一个 TypeScript 配置文件:
1.生成 tsconfig.json 文件:
tsc --init
2.常用配置选项(编辑生成的 tsconfig.json ):
TypeScript
{
"compilerOptions": {
"target": "ES2020", // 编译目标 JavaScript 版本
"module": "commonjs", // 使用的模块系统
"outDir": "./dist", // 输出目录
"rootDir": "./src", // 源代码目录
"strict": true, // 启用所有严格类型检查选项
"esModuleInterop": true, // 启用更好的 CommonJS 模块互操作性
"skipLibCheck": true, // 跳过库文件的类型检查
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"], // 包含的文件
"exclude": ["node_modules"] // 排除的目录
}
默认的
TypeScript
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
// "rootDir": "./src",
// "outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "esnext",
"types": [],
// For nodejs:
// "lib": ["esnext"],
// "types": ["node"],
// and npm install -D @types/node
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Style Options
// "noImplicitReturns": true,
// "noImplicitOverride": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "noPropertyAccessFromIndexSignature": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
}
}
常用编译命令
# 编译单个文件
tsc filename.ts
# 监视文件变化,自动编译
tsc filename.ts --watch
# 使用配置文件编译项目
tsc
# 监视整个项目
tsc --watch
安装额外工具
安装 TypeScript 声明文件
许多 JavaScript 库有类型定义,可以安装以获得更好的类型支持:
# 安装 Node.js 类型定义
npm install --save-dev @types/node
# 安装特定库的类型定义
npm install --save-dev @types/jquery
安装 ts-node(直接运行 TypeScript 文件)
npm install -g ts-node
使用 ts-node 运行 TypeScript 文件而无需先编译:
ts-node filename.ts
在代码编辑器中设置 TypeScript
Visual Studio Code
VS Code 对 TypeScript 有内置支持,但您可以:
- 安装 "TypeScript Importer" 扩展自动导入模块
- 安装 "TypeScript Hero" 更好地组织导入
其他编辑器
- WebStorm:内置 TypeScript 支持
- Sublime Text:安装 "TypeScript" 插件
- Atom:安装 "atom-typescript" 包
TypeScript 特性
TypeScript 作为 JavaScript 的超集,添加了许多强大的类型系统和编程特性。
1. 静态类型系统
TypeScript 最显著的特性是静态类型系统,它允许在编译时检测类型错误,而不是等到运行时才发现。
基本类型注解
TypeScript
// 基本类型
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let list: number[] = [1, 2, 3];
let x: [string, number] = ["hello", 10]; // 元组
// 输出基本类型
console.log("基本类型输出:");
console.log("isDone:", isDone);
console.log("decimal:", decimal);
console.log("color:", color);
console.log("list:", list);
console.log("x:", x);
// 枚举
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
// 输出枚举
console.log("\n枚举输出:");
console.log("Color.Green:", c);
// any 类型 - 可以是任意类型
let notSure: any = 4;
notSure = "maybe a string";
// 输出any类型
console.log("\nany类型输出:");
console.log("notSure:", notSure);
// void 类型 - 通常用于函数返回值
function warnUser(): void {
console.log("This is a warning message");
}

2. 接口 (Interfaces)
接口定义了对象的结构,确保对象符合特定的形状。
TypeScript
interface Person {
name: string;
age: number;
// 可选属性
nickname?: string;
// 只读属性
readonly id: number;
}
function greetPerson(person: Person): string {
return `Hello, ${person.name}!`;
}
// 正确使用
let user: Person = { id: 1, name: "Alice", age: 30 };
greetPerson(user);
// 错误 - 缺少必需属性
// let invalidUser: Person = { name: "Bob" };

3. 类 (Classes)
TypeScript 提供了完整的基于类的面向对象编程支持。
TypeScript
class Animal {
// 私有属性
private name: string;
// 受保护的属性
protected species: string;
// 公共属性
public age: number;
constructor(name: string, species: string, age: number) {
this.name = name;
this.species = species;
this.age = age;
}
// 公共方法
public move(distanceInMeters: number): void {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
// 私有方法
private sleep(): void {
console.log(`${this.name} is sleeping.`);
}
}
// 继承
class Dog extends Animal {
constructor(name: string, age: number) {
super(name, "Canine", age);
}
public bark(): void {
console.log("Woof! Woof!");
}
}
// 创建实例并调用方法
const myDog = new Dog("Buddy", 3);
console.log(`Dog's name: ${myDog["name"]}`); // 注意:name是私有属性,这里只是为了演示
console.log(`Dog's age: ${myDog.age}`);
myDog.bark();
myDog.move(10);

4. 泛型 (Generics)
泛型使代码更加灵活和可重用,同时保持类型安全。
TypeScript
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString");
let output2 = identity<number>(100);
// 泛型接口
interface GenericIdentityFn<T> {
(arg: T): T;
}
let myIdentity: GenericIdentityFn<number> = identity;
// 泛型类
class GenericNumber<T> {
zeroValue: T = {} as T; // 添加初始化表达式
add: (x: T, y: T) => T = (x, y) => x; // 添加初始化表达式
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
// 添加输出语句
console.log("泛型函数输出:");
console.log("output1:", output1);
console.log("output2:", output2);
console.log("泛型接口输出:");
console.log("myIdentity(5):", myIdentity(5));
console.log("泛型类输出:");
console.log("zeroValue:", myGenericNumber.zeroValue);
console.log("add(10, 20):", myGenericNumber.add(10, 20));
// 使用字符串类型的泛型类
let stringGeneric = new GenericNumber<string>();
stringGeneric.zeroValue = "";
stringGeneric.add = function (x, y) {
return x + y;
};
console.log("字符串类型的泛型类:");
console.log("zeroValue:", stringGeneric.zeroValue);
console.log(
'add("Hello, ", "World!"):',
stringGeneric.add("Hello, ", "World!")
);

5. 联合类型与交叉类型
联合类型 (Union Types)
联合类型表示一个值可以是几种类型之一。
TypeScript
// 联合类型
function displayValue(value: string | number): void {
if (typeof value === "string") {
console.log(`String value: ${value.toUpperCase()}`);
} else {
console.log(`Number value: ${value.toFixed(2)}`);
}
}
console.log("=== 联合类型示例 ===");
console.log("处理字符串值:");
displayValue("hello");
console.log("处理数字值:");
displayValue(42.5);
// 更多示例
console.log("=== 更多联合类型示例 ===");
const stringValue: string | number = "TypeScript";
console.log("当前值为字符串:", stringValue);
const numberValue: string | number = 2023;
console.log("当前值为数字:", numberValue);
// 联合类型函数
function processValue(input: string | number): string {
return typeof input === "string"
? `处理字符串: ${input.length}个字符`
: `处理数字: ${input * 2}`;
}
console.log("=== 联合类型函数示例 ===");
console.log(processValue("联合类型"));
console.log(processValue(50));

交叉类型 (Intersection Types)
交叉类型将多个类型合并为一个类型。
TypeScript
interface BusinessPartner {
name: string;
credit: number;
}
interface Identity {
id: number;
name: string;
}
type Employee = BusinessPartner & Identity;
let emp: Employee = {
id: 100,
name: "John",
credit: 7000,
};
// 添加输出语句
console.log("=== 交叉类型示例 ===");
console.log("员工信息:");
console.log(`ID: ${emp.id}`);
console.log(`姓名: ${emp.name}`);
console.log(`信用额度: ${emp.credit}`);
// 使用函数处理交叉类型
function displayEmployeeInfo(employee: Employee): void {
console.log(`
员工 ${employee.name} (ID: ${employee.id}) 的信用额度为 ${employee.credit}`);
}
displayEmployeeInfo(emp);
// 检查属性是否存在
function hasHighCredit(employee: Employee): boolean {
return employee.credit > 7500;
}
console.log("=== 信用额度检查 ===");
console.log(`${emp.name} 是否有高信用额度: ${hasHighCredit(emp)}`);

6. 类型守卫 (Type Guards)
类型守卫是一些表达式,它们在运行时检查类型,帮助 TypeScript 缩小类型范围。
TypeScript
// 使用 typeof 的类型守卫
function padLeft(value: string, padding: string | number): string {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
// 使用 in 操作符的类型守卫
interface Car {
drive(): void;
}
interface Boat {
sail(): void;
}
function useVehicle(vehicle: Car | Boat) {
if ("drive" in vehicle) {
vehicle.drive(); // TypeScript 知道这是 Car
} else {
vehicle.sail(); // TypeScript 知道这是 Boat
}
}
// 添加输出语句
console.log("=== 类型守卫示例 ===");
console.log(`"${padLeft("Hello", 5)}"`);
console.log(`"${padLeft("World", "---")}"`);
const myCar: Car = {
drive: () => console.log("汽车正在行驶...")
};
const myBoat: Boat = {
sail: () => console.log("小船正在航行...")
};
console.log("使用汽车:");
useVehicle(myCar);
console.log("使用小船:");
useVehicle(myBoat);

7. 空值检查 (Null Checks)
TypeScript 提供了严格的空值检查选项,帮助避免常见的空引用错误。
TypeScript
// 启用严格空值检查后
function getNameFromUser(user?: { name: string }): string {
// 错误: 'user' 可能为 'undefined'
// return user.name;
// 正确方式
if (user) {
return user.name;
}
return "Anonymous";
}
// 非空断言操作符
function getDisplayName(user: { name: string } | null): string {
// 告诉 TypeScript 我们确定 user 不为 null
return user!.name;
}

8. 模块系统
TypeScript 支持现代 JavaScript 模块系统,使代码组织更加清晰。
TypeScript
// math.ts
const add = (x: number, y: number): number => {
return x + y;
};
function subtract(x: number, y: number): number {
return x - y;
}
module.exports = {
add,
subtract,
};
// app.ts
const { add, subtract } = require("./math");
console.log(add(5, 3)); // 8
console.log(subtract(10, 4)); // 6
// 默认导出
class Calculator {
add(x: number, y: number): number {
return x + y;
}
}
// 导入默认导出
module.exports = Calculator;
在 "verbatimModuleSyntax" 模式下,不允许在 CommonJS 模块中使用 ESM 语法
9. 高级类型技巧
映射类型 (Mapped Types)
TypeScript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User {
name: string;
age: number;
}
// 创建一个所有属性都是只读的 User 类型
type ReadonlyUser = Readonly<User>;
// 创建一个所有属性都是可选的 User 类型
type PartialUser = Partial<User>;
// 添加输出语句
console.log("=== 映射类型示例 ===");
const user: User = { name: "Alice", age: 30 };
console.log("原始用户:", user);
const readonlyUser: ReadonlyUser = { name: "Bob", age: 25 };
console.log("只读用户:", readonlyUser);
const partialUser: PartialUser = { name: "Charlie" };
console.log("部分用户:", partialUser);

条件类型 (Conditional Types)
TypeScript
type NonNullable<T> = T extends null | undefined ? never : T;
type ExtractType<T, U> = T extends U ? T : never;
// 示例
type StringOrNumber = string | number;
type OnlyString = ExtractType<StringOrNumber, string>; // string
// 添加输出语句
console.log("=== 条件类型示例 ===");
// NonNullable 示例
const nullableString: string | null = "Hello";
const nonNullString: NonNullable<string | null> = "World";
console.log("可为空的字符串:", nullableString);
console.log("非空字符串:", nonNullString);
// ExtractType 示例
const stringOrNumber: StringOrNumber = "TypeScript";
console.log("字符串或数字:", stringOrNumber);
console.log("OnlyString 类型检查:", typeof stringOrNumber === "string" ? "是字符串" : "不是字符串");

10. 类型推断
TypeScript 能够根据上下文自动推断类型,减少显式类型注解的需要。
TypeScript
// 类型推断示例
let x = 3; // TypeScript 推断 x 的类型为 number
// 函数返回类型推断
function add(a: number, b: number) {
return a + b; // TypeScript 推断返回类型为 number
}
// 添加输出语句
console.log("=== 类型推断示例 ===");
console.log("变量 x 的值:", x);
console.log("变量 x 的类型:", typeof x);
const sum = add(5, 7);
console.log("add(5, 7) 的结果:", sum);
console.log("sum 的类型:", typeof sum);
// 上下文推断示例
console.log("=== 上下文推断示例 ===");
// 定义一个简单的函数来演示上下文推断
function handleMouseDown(mouseEvent: { button: number }) {
console.log("鼠标按钮:", mouseEvent.button);
}
// 模拟鼠标点击事件
console.log("模拟鼠标点击事件:");
handleMouseDown({ button: 0 }); // 左键点击

11. 声明文件与 DefinitelyTyped
TypeScript 使用声明文件(.d.ts)来描述 JavaScript 库的类型。
TypeScript
// 声明全局变量
declare var $: (selector: string) => any;
// 声明模块
declare module "my-library" {
export function doSomething(): void;
}
通过 DefinitelyTyped,大多数流行的 JavaScript 库都有可用的类型定义:
TypeScript
npm install --save-dev @types/node @types/react @types/express
TypeScript 提前支持了一些还未在所有环境中普及的 ES 特性,如装饰器(Decorators)、异步迭代器等
总结
TypeScript 的这些特性使它成为大型项目开发的理想选择:
- 类型安全:在编译时捕获错误,减少运行时问题
- 更好的代码组织:通过接口、类和模块系统
- 增强的工具支持:提供精确的代码补全、重构和导航
- 现代 JavaScript 特性:支持最新的 ECMAScript 标准
- 渐进式采用:可以逐步将 JavaScript 项目迁移到 TypeScript
TypeScript 基础语法
tsc 常用编译参数如下表所示:
| 序号 | 编译参数说明 |
|---|---|
| 1. | --help 显示帮助信息 |
| 2. | --module 载入扩展模块,需要一个参数 |
| 3. | --target 设置 ECMA 版本,需要一个参数 |
| 4. | --declaration 额外生成一个 .d.ts 扩展名的文件。 tsc ts-hw.ts --declaration 以上命令会生成 ts-hw.d.ts、ts-hw.js 两个文件。 |
| 5. | --removeComments 删除文件的注释 |
| 6. | --out 编译多个文件并合并到一个输出的文件 |
| 7. | --sourcemap 生成一个 sourcemap (.map) 文件。 sourcemap 是一个存储源代码与编译代码对应位置映射的信息文件。 |
| 8. | --module noImplicitAny 在表达式和声明上有隐含的 any 类型时报错 |
| 9. | --watch 在监视模式下运行编译器。会监视输出文件,在它们改变时重新编译。 |
tsc --help

tsc --module

tsc--target

tsc --removeComments

TypeScript 注释
注释用于解释代码,提高代码可读性。
单行注释
TypeScript
// 这是一个单行注释
let count: number = 0; // 初始化计数器
// 函数说明:计算两个数的和
function add(a: number, b: number): number {
return a + b; // 返回计算结果
}
多行注释
TypeScript
/*
* 这是一个多行注释
* 用于详细解释函数的功能
* 参数说明:
* @param name 用户姓名
* @param age 用户年龄
* @returns 用户信息字符串
*/
function createUserProfile(name: string, age: number): string {
return `姓名: ${name}, 年龄: ${age}`;
}
/**
* 计算圆的面积
* @param radius 圆的半径
* @returns 圆的面积
* @throws {Error} 当半径为负数时抛出错误
*/
function calculateCircleArea(radius: number): number {
if (radius < 0) {
throw new Error("半径不能为负数");
}
return Math.PI * radius * radius;
}
JSDoc 注释
TypeScript
/**
* 用户类
* @class
* @classdesc 表示系统中的用户实体
*/
class User {
/**
* 用户ID
* @type {number}
*/
public id: number;
/**
* 用户名
* @type {string}
*/
public name: string;
/**
* 创建用户实例
* @param {number} id - 用户ID
* @param {string} name - 用户名
* @param {number} [age] - 用户年龄(可选)
*/
constructor(id: number, name: string, age?: number) {
this.id = id;
this.name = name;
}
/**
* 获取用户信息
* @returns {string} 用户信息字符串
*/
getInfo(): string {
return `ID: ${this.id}, 姓名: ${this.name}`;
}
}
TypeScript 基本结构
TypeScript 基础类型
TypeScript
// 定义枚举类型,用于表示用户的角色
enum Role {
Admin,
User,
Guest,
}
// 使用 interface 定义用户的结构
interface User {
id: number; // number 类型,用于唯一标识用户
username: string; // string 类型,表示用户名
isActive: boolean; // boolean 类型,表示用户是否激活
role: Role; // enum 类型,用于表示用户角色
hobbies: string[]; // array 类型,存储用户的兴趣爱好
contactInfo: [string, number]; // tuple 类型,包含电话号码的元组,格式为:[区域码, 电话号码]
}
// 创建用户对象,符合 User 接口的结构
const user: User = {
id: 1,
username: "Alice",
isActive: true,
role: Role.User,
hobbies: ["Reading", "Gaming"],
contactInfo: ["+1", 123456789],
};
// 定义一个返回字符串的函数来获取用户信息
function getUserInfo(user: User): string {
return `User ${user.username} is ${user.isActive ? "active" : "inactive"} with role ${Role[user.role]}`;
}
// 使用 void 类型定义一个函数,专门打印用户信息
function printUserInfo(user: User): void {
console.log(getUserInfo(user));
}
// 定义一个 union 类型的函数参数,接受用户 ID(number)或用户名(string)
function findUser(query: number | string): User | undefined {
// 使用 typeof 来判断 query 的类型
if (typeof query === "number") {
// 如果是数字,则根据 ID 查找用户
return query === user.id ? user : undefined;
} else if (typeof query === "string") {
// 如果是字符串,则根据用户名查找用户
return query === user.username ? user : undefined;
}
return undefined;
}
// 定义一个 never 类型的函数,用于处理程序的异常情况
function throwError(message: string): never {
throw new Error(message);
}
// 使用 any 类型处理未知类型的数据
let unknownData: any = "This is a string";
unknownData = 42; // 重新赋值为数字,类型为 any
// 使用 unknown 类型处理不确定的数据,更加安全
let someData: unknown = "Possible data";
if (typeof someData === "string") {
console.log(`Length of data: ${(someData as string).length}`);
}
// 调用各个函数并测试
printUserInfo(user); // 打印用户信息
console.log(findUser(1)); // 根据 ID 查找用户
console.log(findUser("Alice")); // 根据用户名查找用户
// 使用 null 和 undefined 类型的变量
let emptyValue: null = null;
let uninitializedValue: undefined = undefined;

TypeScript 变量声明
**注意:**变量不要使用 name 否则会与 DOM 中的全局 window 对象下的 name 属性出现了重名。
类型断言
TypeScript
var str = "1";
var str2: number = <number>(<any>str); //str、str2 是 string 类型
console.log(str2);

类型判断

TypeScript 变量声明
TypeScript 主要包含以下几种运算:
- 算术运算符
- 逻辑运算符
- 关系运算符
- 按位运算符
- 赋值运算符
- 三元/条件运算符
- 字符串运算符
- 类型运算符
TypeScript 条件语句
TypeScript 循环
for...of 、forEach、every 和 some 循环
1. for...of 循环
for...of 是 ES6 引入的一种遍历可迭代对象(包括数组、字符串、Map、Set 等)的语法结构。
TypeScript
// 基本语法
const numbers: number[] = [1, 2, 3, 4, 5];
for (const num of numbers) {
console.log(num);
}
// 遍历字符串
const greeting: string = "Hello";
for (const char of greeting) {
console.log(char); // H e l l o
}
// 在 for...of 中获取索引
const fruits: string[] = ["apple", "banana", "orange"];
for (const [index, fruit] of fruits.entries()) {
console.log(`${index}: ${fruit}`);
}

2. forEach 方法
forEach 是数组的一个方法,对数组的每个元素执行一次提供的函数。
TypeScript
// 基本用法
const numbers: number[] = [1, 2, 3, 4, 5];
numbers.forEach((num) => {
console.log(num);
});
// 带索引的用法
const colors: string[] = ["red", "green", "blue"];
colors.forEach((color, index) => {
console.log(`${index}: ${color}`);
});
// 完整回调函数参数
colors.forEach((color, index, array) => {
console.log(`${index}: ${color}`, array);
});
// 使用 thisArg 参数
const counter = {
count: 0,
increment: function(value: number) {
this.count += value;
console.log(`Current count: ${this.count}`);
}
};
const values = [10, 20, 30];
values.forEach(function(value) {
this.increment(value);
}, counter);

3. every 方法
every 方法测试数组中的所有元素是否都通过了指定函数的测试。它返回一个布尔值。
TypeScript
// 检查所有元素是否满足条件
const numbers = [2, 4, 6, 8, 10];
const allEven = numbers.every((num) => num % 2 === 0);
console.log(allEven); // true
const mixedNumbers = [1, 2, 4, 6];
const allEvenMixed = mixedNumbers.every((num) => num % 2 === 0);
console.log(allEvenMixed); // false
// 实际应用场景
const users = [
{ name: "Alice", age: 25, active: true },
{ name: "Bob", age: 30, active: true },
{ name: "Charlie", age: 35, active: true }
];
// 检查所有用户是否都是活跃的
const allActive = users.every(user => user.active);
console.log(allActive); // true
// 检查所有用户是否都成年
const allAdults = users.every(user => user.age >= 18);
console.log(allAdults); // true

4. some 方法
some 方法测试数组中是否至少有一个元素通过了指定函数的测试。它返回一个布尔值。
TypeScript
// 检查是否有元素满足条件
const numbers = [1, 3, 5, 8, 10];
const hasEven = numbers.some((num) => num % 2 === 0);
console.log(hasEven); // true
const allOdd = [1, 3, 5, 7];
const hasEvenOdd = allOdd.some((num) => num % 2 === 0);
console.log(hasEvenOdd); // false
// 实际应用场景
const products = [
{ name: "Laptop", price: 1000, inStock: true },
{ name: "Mouse", price: 25, inStock: false },
{ name: "Keyboard", price: 75, inStock: true }
];
// 检查是否有缺货商品
const hasOutOfStock = products.some(product => !product.inStock);
console.log(hasOutOfStock); // true
// 检查是否有高价商品
const hasExpensive = products.some(product => product.price > 500);
console.log(hasExpensive); // true

方法比较与使用场景
| 方法 | 返回值 | 用途 | 是否可中断 |
|---|---|---|---|
for...of |
无 | 遍历元素并执行操作 | 可以使用 break 中断 |
forEach |
无 | 遍历元素并执行操作 | 不可中断 |
every |
布尔值 | 检查所有元素是否满足条件 | 在第一个不满足条件的元素处停止 |
some |
布尔值 | 检查是否有元素满足条件 | 在第一个满足条件的元素处停止 |
性能考虑
- 对于大型数组,
for...of循环通常比forEach更快,因为它是语言级别的结构,减少了函数调用的开销 every和some具有短路行为,在找到匹配项时会立即停止遍历,这比手动遍历整个数组更高效- 如果需要在遍历过程中提前退出,使用
for...of配合break或return是更好的选择
TypeScript 函数
在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 ?。
函数的最后一个命名参数以 ... 为前缀,它将成为一个由剩余参数组成的数组,索引值从0(包括)到.length(不包括)。
TypeScript Number
TypeScript String(字符串)
通常情况下,TypeScript 推荐直接使用 string 字面量类型,以简化代码,提高性能,避免不必要的类型转换和复杂性。
TypeScript Array(数组)
TypeScript Map 对象
TypeScript 元组
TypeScript 联合类型
TypeScript 接口
TypeScript 命名空间
TypeScript 中命名空间使用 namespace 来定义
TypeScript 模块
JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js
TypeScript 声明文件
declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对
declare 定义的类型只会用于编译时的检查,编译结果中会被删除。
声明文件
声明文件以 .d.ts 为后缀