TypeScript学习入门笔记
一. 环境搭建
1.1 安装 Node.js 和 npm
TypeScript 的编译器是基于 Node.js 的,因此我们首先需要安装 Node.js。安装 Node.js 之后,npm(Node.js 的包管理器)会自动安装,这对安装 TypeScript 至关重要。
-
下载 Node.js: 前往 Node.js 官网,下载适合你操作系统的版本。建议选择“LTS(长期支持版本)”版本,稳定且适合大多数开发项目。
-
验证安装: 安装完成后,打开终端(Windows 用户可以使用命令提示符或 PowerShell),输入以下命令来验证安装是否成功。
node -v npm -v
1.2 安装 TypeScript
接下来,我们通过 npm 全局安装 TypeScript 编译器 tsc
。在终端中输入以下命令:
npm install -g typescript
安装完成后,可以通过以下命令验证安装是否成功:
tsc -v
1.3 安装代码编辑器
接下来我们需要一个支持 TypeScript 的代码编辑器。大多数现代的编辑器都提供了对 TypeScript 的支持,但最流行的选择是 Visual Studio Code(简称 VSCode)。
-
下载 VSCode: 访问 VSCode 官网,下载适用于你操作系统的版本。
-
安装 TypeScript 插件: VSCode 自带 TypeScript 支持,但可以通过插件增强其功能。可以在扩展市场中搜索并安装
TypeScript Extension Pack
,以增强 TypeScript 相关的代码提示、调试、重构功能。
1.4 创建 TypeScript 项目
有了 TypeScript 编译器和编辑器,我们可以开始创建一个 TypeScript 项目。以下是初始化一个项目的步骤。
-
创建项目文件夹: 在命令行或文件管理器中创建一个新的项目文件夹,例如
my-ts-project
。mkdir my-ts-project cd my-ts-project
-
初始化项目: 使用
npm init
来初始化一个新的项目,它会创建一个package.json
文件来管理项目的依赖项。npm init -y
-
安装 TypeScript: 为了确保项目使用本地安装的 TypeScript,执行以下命令:
npm install typescript --save-dev
-
初始化 TypeScript 配置文件: 使用 TypeScript 提供的命令生成
tsconfig.json
,它是 TypeScript 项目的配置文件。tsc --init
这会在项目根目录下创建一个默认的
tsconfig.json
文件,文件内容可以根据需要进行修改。通常最基本的配置如下:{ "compilerOptions": { "target": "ES6", // 指定编译后的 JavaScript 版本 "module": "commonjs", // 指定使用的模块化系统 "strict": true, // 启用所有严格类型检查选项 "esModuleInterop": true // 允许兼容 CommonJS 和 ES 模块 }, "exclude": ["node_modules"] // 排除不编译的文件夹 }
-
创建 TypeScript 文件: 在项目文件夹下新建一个
src
文件夹,并在其中创建一个index.ts
文件。// src/index.ts const greeting: string = "Hello, TypeScript!"; console.log(greeting);
-
编译 TypeScript 文件: 在命令行中运行以下命令,将 TypeScript 编译为 JavaScript。
tsc
编译成功后,会在
src
文件夹旁生成一个dist
文件夹,里面包含编译后的 JavaScript 文件:dist/index.js
如果你想实时监控文件变化并自动编译,可以使用
tsc --watch
命令,它会在文件发生变化时自动重新编译。
1.5 使用 ts-node 直接运行 TypeScript 文件
尽管 TypeScript 需要编译为 JavaScript,但在开发过程中,可能想直接运行 TypeScript 文件而不需要手动编译。这里可以借助 ts-node
来实现。
-
安装 ts-node:
npm install -g ts-node
-
运行 TypeScript 文件:
现在你可以使用
ts-node
直接运行.ts
文件,而不需要先编译为 JavaScript。ts-node src/index.ts
1.6 使用工具链
为了提高开发效率,还可以引入一些工具来管理和优化项目。
-
ESLint + TypeScript: 安装并配置 ESLint 来保证代码风格和质量一致性。
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
然后初始化 ESLint:
npx eslint --init
在
.eslintrc.json
中配置 TypeScript 解析器:{ "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ] }
-
Prettier: 用于代码格式化。安装
Prettier
并配置.prettierrc
文件。npm install --save-dev prettier
配置
.prettierrc
文件:{ "semi": true, "singleQuote": true, "trailingComma": "es5" }
通过这些步骤,我们已经拥有一个功能齐全的 TypeScript 开发环境了,现在可以开始编写和调试 TypeScript 代码了。
二. 数据类型
TypeScript提供了一套丰富的数据类型系统,可以帮助开发者明确每个变量的类型,从而避免许多潜在的运行时错误。以下是常见的数据类型和它们的实际应用场景。
-
number
: 用于处理所有数字类型,包括整数和浮点数。let decimal: number = 10; // 十进制数 let hex: number = 0xf00d; // 十六进制数 let binary: number = 0b1010; // 二进制数 let octal: number = 0o744; // 八进制数
-
string
: 用于处理文本。可以使用双引号(""
)、单引号(''
)或模板字符串(let color: string = "blue"; let fullName: string = `Bob Bobbington`; let age: number = 37; let sentence: string = `Hello, my name is ${ fullName}. I'll be ${ age + 1} years old next month.`;
-
boolean
: 布尔值可以用于条件判断。let isDone: boolean = false;
-
array
: 数组可以通过两种方式定义,类型后跟上[]
或使用Array<类型>
。let list: number[] = [1, 2, 3]; let anotherList: Array<number> = [4, 5, 6];
-
any
: 允许在编写代码时临时跳过类型检查,适合处理不确定的数据类型。let notSure: any = 4; notSure = "maybe a string instead"; // 正确 notSure = false; // 正确
-
联合类型(Union Types): 一个变量可以是多种类型之一,这通过
|
符号定义。let value: string | number; value = "Hello"; // 合法 value = 42; // 合法
三. 元组(Tuple)
元组允许你定义一个已知长度和已知类型的数组,且各元素的类型可以不同。这使得它特别适用于需要处理固定结构数据的场景。
let person: [string, number];
person = ["John", 25]; // 正确
元组可以用于函数的返回值,当函数返回多个不同类型的值时,使用元组可以更好地约束返回的类型。
function getUserInfo(): [string, number] {
return ["Alice", 30];
}
let [username, age] = getUserInfo();
console.log(username); // Alice
console.log(age); // 30
元组也支持可选元素和标签化:
let tupleWithOptional: [string, number?] = ["TypeScript"];
let labeledTuple: [name: string, age: number] = ["Bob", 45];
四. 枚举(Enum)
枚举用于定义一组命名的常量,可以方便地管理具有固定取值范围的变量。默认情况下,枚举的值从 0
开始递增,也可以手动指定值。
enum Direction {
Up = 1,
Down,
Left,
Right
}
let dir: Direction = Direction.Left;
console.log(dir); // 输出:3
反向映射是枚举的一个特性,可以通过枚举的值获取对应的名称:
console.log(Direction[1]); // 输出:Up
异构枚举允许在同一个枚举中包含数字和字符串:
enum Response {
No = 0,
Yes = "YES"
}
五. 函数(Function)
TypeScript允许对函数参数和返回值进行类型约束。这不仅使函数定义更加清晰,还减少了错误。
-
基本函数定义:
function sum(x: number, y: number): number { return x + y; }
-
可选参数: 可选参数通过
?
表示,且必须放在参数列表末尾。function buildName(firstName: string, lastName?: string): string { return lastName ? `${ firstName} ${ lastName}` : firstName; }
-
默认参数: TypeScript允许为参数设置默认值。
function buildFullName(firstName: string, lastName: string = "Smith"): string { return `${ firstName} ${ lastName}`; }
-
剩余参数(Rest Parameters): 剩余参数可以将不确定数量的参数收集为一个数组。
function addNumbers(...numbers: number[]): number { return numbers.reduce((a, b) => a + b, 0); } console.log(addNumbers(1, 2, 3, 4)); // 输出 10
六. 接口(Interface)
接口是 TypeScript 中最常用的工具之一,它不仅能定义对象的结构,还可以为函数和类提供约束。
-
基本接口定义:
interface Point { x: number; y: number; } function printPoint(p: Point): void { console.log(`x: ${ p.x}, y: ${ p.y}`); } let point: Point = { x: 10, y: 20 }; printPoint(point); // 输出 x: 10, y: 20
-
可选属性: 接口中的属性可以是可选的。
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): { color: string; area: number} { let newSquare = { color: "white", area: 100}; if (config.color) { newSquare.color = config.color; } if (config.width) { newSquare.area = config.width * config.width; } return newSquare; }
-
函数类型接口: 接口也可以用于定义函数类型。
interface SearchFunc { (source: string, subString: string): boolean; } let mySearch: SearchFunc; mySearch = function(src: string, sub: string): boolean { return src.indexOf(sub) > -1; }
七. 类(Class)
TypeScript的类提供了更多的面向对象编程特性,包括继承、访问修饰符和抽象类等。
-
基本类:
class Animal { name: string; constructor(name: string) { this.name = name; } move(distance: number = 0): void { console.log(`${ this.name} moved ${ distance} meters.`); } } let cat = new Animal("Cat"); cat.move(5);
-
继承: 类可以通过
extends
关键字继承另一个类。class Dog extends Animal { bark(): void { console.log("Woof! Woof!"); } } let dog = new Dog("Buddy"); dog.bark(); // 输出 Woof! Woof! dog.move(10); // 输出 Buddy moved 10 meters.
-
访问修饰符: TypeScript提供
public
、private
、protected
来控制成员的访问权限。class Person { protected name: string; constructor(name: string) { this.name = name; } } class Employee extends Person { private department: string; constructor(name: string, department: string) { super(name); this.department = department; } public getDetails(): string { return `${ this.name} works in ${ this.department}.`; } } let employee = new Employee("Alice", "Engineering"); console.log(employee.getDetails());
八. 泛型(Generics)
泛型是 TypeScript 的一项强大特性,它使得函数、类、接口等在使用时可以适应多种类型。
-
泛型函数:
function identity<T>(arg: T): T { return arg; } let output = identity<string>("Hello"); let output2 = identity<number>(42);
-
泛型类:
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
九. 模块(Modules)
模块是 TypeScript 中组织代码的主要手段。通过 import 和 export,我们可以将代码分割成多个文件并进行重用。
- 导出:
export class User {
constructor(public name: string) {
}
}
- 导入:
import {
User } from './User';
let user = new User("Alice");