什么是 TypeScript?

TypeScript 是由微软开发的 JavaScript 的超集,它添加了静态类型定义。TypeScript 代码会被编译成纯 JavaScript 代码,可以在任何支持 JavaScript 的环境中运行。

TypeScript 的核心特性

  1. 静态类型:在编译时捕获类型错误

  2. 类型推断:自动推断变量类型

  3. 接口:定义对象的结构

  4. :支持面向对象编程

  5. 泛型:创建可重用的组件

  6. 装饰器:元编程支持

  7. ES6+ 支持:支持最新的 JavaScript 特性

TypeScript 的优势

  • 更好的开发体验:智能提示、自动补全

  • 更少的运行时错误:编译时捕获错误

  • 更好的代码可维护性:类型作为文档

  • 更好的团队协作:明确的类型定义

  • 渐进式采用:可以逐步迁移到 TypeScript

安装 TypeScript

使用 npm 安装

# 全局安装
npm install -g typescript

# 或者在项目中安装
npm install --save-dev typescript

验证安装

tsc --version

初始化项目

# 创建项目目录
mkdir my-typescript-project
cd my-typescript-project

# 初始化 package.json
npm init -y

# 安装 TypeScript
npm install --save-dev typescript

# 创建 tsconfig.json
npx tsc --init

第一个 TypeScript 程序

创建 TypeScript 文件

创建 hello.ts 文件:

// 基本类型注解
let message: string = "Hello, TypeScript!";
console.log(message);

编译 TypeScript

# 编译单个文件
tsc hello.ts

# 这会生成 hello.js 文件

编译后的 JavaScript

var message = "Hello, TypeScript!";
console.log(message);

使用 ts-node 直接运行

# 安装 ts-node
npm install --save-dev ts-node

# 直接运行 TypeScript 文件
npx ts-node hello.ts

TypeScript 基础语法

变量声明

// 显式类型注解
let username: string = "Alice";
let age: number = 25;
let isActive: boolean = true;

// 类型推断
let city = "Beijing";  // 自动推断为 string
let count = 100;       // 自动推断为 number

// 常量
const PI: number = 3.14159;
const MAX_SIZE: number = 100;

数组

// 类型注解
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["Alice", "Bob", "Charlie"];

// 泛型语法
let scores: Array<number> = [95, 87, 92];

// 混合类型数组
let mixed: (string | number)[] = [1, "two", 3, "four"];

元组

// 固定长度和类型的数组
let person: [string, number] = ["Alice", 25];

// 访问元素
console.log(person[0]);  // "Alice"
console.log(person[1]);  // 25

// 可选元素
let optional: [string, number, boolean?] = ["Bob", 30];

对象

// 对象类型
let user: {
    name: string;
    age: number;
    email?: string;  // 可选属性
} = {
    name: "Alice",
    age: 25
};

// 访问属性
console.log(user.name);
console.log(user.email);  // undefined

any 类型

// any 类型可以接受任何值
let anything: any = 42;
anything = "hello";
anything = true;

// 避免过度使用 any
function process(data: any) {
    // 失去类型检查
    console.log(data.toUpperCase());  // 可能运行时错误
}

unknown 类型

// 更安全的 any
let value: unknown = "hello";

// 使用前需要类型检查
if (typeof value === "string") {
    console.log(value.toUpperCase());  // 安全
}

void 类型

// 表示没有返回值
function log(message: string): void {
    console.log(message);
}

// never 类型 - 永不返回
function error(message: string): never {
    throw new Error(message);
}

函数

函数类型

// 函数声明
function add(a: number, b: number): number {
    return a + b;
}

// 箭头函数
const multiply = (a: number, b: number): number => {
    return a * b;
};

// 可选参数
function greet(name: string, greeting?: string): string {
    return greeting ? `${greeting}, ${name}!` : `Hello, ${name}!`;
}

// 默认参数
function createName(first: string, last: string = "Smith"): string {
    return `${first} ${last}`;
}

// 剩余参数
function sum(...numbers: number[]): number {
    return numbers.reduce((total, num) => total + num, 0);
}

函数类型表达式

// 定义函数类型
type MathOperation = (a: number, b: number) => number;

// 使用函数类型
const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;

// 作为参数
function calculate(operation: MathOperation, a: number, b: number): number {
    return operation(a, b);
}

console.log(calculate(add, 5, 3));      // 8
console.log(calculate(subtract, 5, 3)); // 2

控制流

条件语句

// if-else
function checkAge(age: number): string {
    if (age < 18) {
        return "未成年";
    } else if (age < 65) {
        return "成年";
    } else {
        return "老年";
    }
}

// 三元运算符
const isAdult = (age: number): boolean => age >= 18;

循环

// for 循环
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// for...of
const colors: string[] = ["red", "green", "blue"];
for (const color of colors) {
    console.log(color);
}

// for...in
const person = { name: "Alice", age: 25 };
for (const key in person) {
    console.log(`${key}: ${person[key]}`);
}

// while 循环
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

类型断言

类型断言语法

// 尖括号语法
let value: any = "hello world";
let strLength: number = (<string>value).length;

// as 语法(推荐)
let strLength2: number = (value as string).length;

使用场景

// DOM 元素
const input = document.getElementById("username") as HTMLInputElement;
input.value = "Alice";

// JSON 解析
const json = '{"name": "Alice", "age": 25}';
const user = JSON.parse(json) as { name: string; age: number };
console.log(user.name);

联合类型和交叉类型

联合类型

// 联合类型
type ID = string | number;

function printId(id: ID) {
    console.log(`ID: ${id}`);
}

printId(101);
printId("abc-123");

// 类型守卫
function processValue(value: string | number) {
    if (typeof value === "string") {
        console.log(value.toUpperCase());
    } else {
        console.log(value.toFixed(2));
    }
}

交叉类型

// 交叉类型
type Person = {
    name: string;
    age: number;
};

type Employee = {
    employeeId: number;
    department: string;
};

type EmployeePerson = Person & Employee;

const employee: EmployeePerson = {
    name: "Alice",
    age: 25,
    employeeId: 1001,
    department: "Engineering"
};

字面量类型

字符串字面量

// 字符串字面量类型
type Direction = "up" | "down" | "left" | "right";

function move(direction: Direction) {
    console.log(`Moving ${direction}`);
}

move("up");    // 正确
// move("diagonal");  // 错误

数字字面量

// 数字字面量类型
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;

function rollDice(): DiceRoll {
    return Math.floor(Math.random() * 6) + 1 as DiceRoll;
}

布尔字面量

// 布尔字面量类型
type Success = true;
type Failure = false;

function checkResult(result: Success | Failure) {
    if (result) {
        console.log("操作成功");
    } else {
        console.log("操作失败");
    }
}

类型别名

创建类型别名

// 基本类型别名
type Age = number;
type Name = string;
type IsActive = boolean;

// 对象类型别名
type User = {
    id: number;
    name: string;
    email: string;
    age?: number;
};

// 函数类型别名
type Validator = (value: string) => boolean;

// 使用类型别名
const validateEmail: Validator = (email) => {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};

枚举

数字枚举

// 数字枚举
enum Direction {
    Up,    // 0
    Down,  // 1
    Left,  // 2
    Right  // 3
}

function move(direction: Direction) {
    console.log(`Moving ${Direction[direction]}`);
}

move(Direction.Up);    // "Moving Up"
move(Direction.Right); // "Moving Right"

字符串枚举

// 字符串枚举
enum Color {
    Red = "RED",
    Green = "GREEN",
    Blue = "BLUE"
}

function setColor(color: Color) {
    console.log(`Color set to ${color}`);
}

setColor(Color.Red);

常量枚举

// 常量枚举
const enum Status {
    Active = "ACTIVE",
    Inactive = "INACTIVE",
    Pending = "PENDING"
}

// 编译后会被内联
console.log(Status.Active);  // "ACTIVE"

总结

本教程介绍了 TypeScript 的基础概念:

  1. TypeScript 简介

    • JavaScript 的超集
    • 添加静态类型
    • 编译成 JavaScript
  2. 安装和配置

    • 使用 npm 安装
    • 初始化项目
    • 配置 tsconfig.json
  3. 基础语法

    • 变量声明和类型注解
    • 数组和元组
    • 对象类型
    • any 和 unknown 类型
  4. 函数

    • 函数类型
    • 可选和默认参数
    • 剩余参数
    • 函数类型表达式
  5. 控制流

    • 条件语句
    • 循环
  6. 高级类型

    • 类型断言
    • 联合类型和交叉类型
    • 字面量类型
    • 类型别名
    • 枚举

TypeScript 为 JavaScript 添加了强大的类型系统,帮助开发者编写更安全、更可维护的代码。

下一步

在下一教程中,我们将深入学习 TypeScript 的基础类型系统,包括:

  • 接口

  • 类型守卫

  • 类型推断

  • 类型兼容性

继续学习 TypeScript,掌握这门强大语言的更多特性!