TypeScript 完全入门指南:从基础到项目配置

一、为什么需要 TypeScript?

JavaScript 是一门动态类型语言,灵活但容易在运行时出现类型相关的错误。TypeScript 作为 JavaScript 的超集,添加了**静态类型系统**,可以在代码运行前发现潜在错误,提升开发体验和代码可维护性。

**主要优势:**

  • 静态类型检查,提前发现错误

  • 更好的代码提示和自动补全

  • 更清晰的自文档化代码

  • 支持最新的 ECMAScript 特性

二、环境搭建与快速开始

2.1 安装 TypeScript

```bash

全局安装 TypeScript

npm install -g typescript

检查版本

tsc --version

2.2 第一个 TS 程序

创建 hello.ts 文件:

typescript

复制代码
// hello.ts
function greet(name: string): string {
    return `Hello, ${name}!`;
}

const message = greet("TypeScript");
console.log(message);

编译运行:

bash

复制代码
# 编译为 JavaScript
tsc hello.ts

# 运行生成的 JS 文件
node hello.js

三、基础数据类型

TypeScript 支持 JavaScript 的所有类型,并增加了额外的类型注解。

3.1 原始类型

typescript

复制代码
// 布尔值let isDone: boolean = false;

// 数字(整数和浮点数)
let age: number = 25;
let price: number = 99.99;

// 字符串
let name: string = "Alice";
let greeting: string = `Hello, ${name}`;

// 空值(void)
function logMessage(message: string): void {
    console.log(message);
}

// null 和 undefined
let u: undefined = undefined;
let n: null = null;

3.2 数组和元组

typescript

复制代码
// 数组两种声明方式
let list1: number[] = [1, 2, 3];
let list2: Array<string> = ["a", "b", "c"];

// 元组(固定长度和类型的数组)
let person: [string, number] = ["John", 30];
// 访问元组元素
console.log(person[0]); // John
console.log(person[1]); // 30

3.3 枚举(enum)

typescript

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

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

let dir: Direction = Direction.Up;
let color: Color = Color.Red;

3.4 Any 和 Unknown

typescript

复制代码
// any - 关闭类型检查(尽量避免使用)
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;

// unknown - 更安全的 any(需要类型收窄)
let uncertain: unknown = "hello";
// uncertain.toUpperCase(); // 错误:unknown 不能直接调用方法

// 类型收窄后才能使用
if (typeof uncertain === "string") {
    console.log(uncertain.toUpperCase());
}

四、接口(Interface)

接口定义对象的结构契约,是 TypeScript 最核心的特性之一。

4.1 基础接口

typescript

复制代码
// 定义用户接口
interface User {
    id: number;
    name: string;
    email: string;
    age?: number;        // 可选属性
    readonly createdAt: Date; // 只读属性
}

// 使用接口
const user: User = {
    id: 1,
    name: "Alice",
    email: "alice@example.com",
    createdAt: new Date()
};

// user.createdAt = new Date(); // 错误:只读属性不能修改

4.2 函数类型接口

typescript

复制代码
interface GreetFunction {
    (name: string, age: number): string;
}

const greet: GreetFunction = (name, age) => {
    return `${name} is ${age} years old`;
};

4.3 接口继承

typescript

复制代码
interface Animal {
    name: string;
    eat(): void;
}

interface Dog extends Animal {
    breed: string;
    bark(): void;
}

const myDog: Dog = {
    name: "Buddy",
    breed: "Golden Retriever",
    eat() {
        console.log(`${this.name} is eating`);
    },
    bark() {
        console.log("Woof!");
    }
};

五、函数高级特性

5.1 函数类型注解

typescript

复制代码
// 完整函数类型
let myAdd: (x: number, y: number) => number = function(x, y) {
    return x + y;
};

// 可选参数和默认参数
function buildName(firstName: string, lastName?: string, title: string = "Mr."): string {
    if (lastName) {
        return `${title} ${firstName} ${lastName}`;
    }
    return `${title} ${firstName}`;
}

console.log(buildName("John"));              // Mr. John
console.log(buildName("John", "Doe"));       // Mr. John Doe
console.log(buildName("John", "Doe", "Dr.")); // Dr. John Doe

5.2 剩余参数

typescript

复制代码
function sum(...numbers: number[]): number {
    return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

5.3 函数重载

typescript

复制代码
// 重载签名
function reverse(str: string): string;
function reverse(arr: any[]): any[];

// 实现签名
function reverse(value: string | any[]): string | any[] {
    if (typeof value === "string") {
        return value.split("").reverse().join("");
    }
    return [...value].reverse();
}

console.log(reverse("hello"));  // "olleh"
console.log(reverse([1, 2, 3])); // [3, 2, 1]

六、高级类型

6.1 联合类型和交叉类型

typescript

复制代码
// 联合类型(或)
type StringOrNumber = string | number;
let value: StringOrNumber = "hello";
value = 123;

// 交叉类型(且)
interface Name {
    name: string;
}
interface Age {
    age: number;
}
type Person = Name & Age;
const p: Person = { name: "Bob", age: 25 };

6.2 类型别名(type)

typescript

复制代码
type Point = {
    x: number;
    y: number;
};

type ID = string | number;

function getPoint(): Point {
    return { x: 10, y: 20 };
}

6.3 类型断言

typescript

复制代码
// 两种语法
let someValue: any = "this is a string";
let strLength1: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length;

6.4 字面量类型

typescript

复制代码
type Direction = "up" | "down" | "left" | "right";
let move: Direction = "up"; // 只能赋值这四个值之一

type Status = 200 | 404 | 500;
let responseStatus: Status = 200;

七、泛型(Generics)

泛型让你创建可重用的组件,能够处理多种类型。

7.1 泛型函数

typescript

复制代码
// 基础泛型
function identity<T>(arg: T): T {
    return arg;
}

// 使用泛型函数
let output1 = identity<string>("hello");
let output2 = identity(100); // 类型推断

// 泛型约束
interface Lengthwise {
    length: number;
}

function logLength<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

logLength("hello");    // 5
logLength([1, 2, 3]);  // 3
// logLength(123);     // 错误:数字没有 length 属性

7.2 泛型接口

typescript

复制代码
interface GenericIdentityFn<T> {
    (arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

7.3 泛型类

typescript

复制代码
class Stack<T> {
    private items: T[] = [];
    
    push(item: T): void {
        this.items.push(item);
    }
    
    pop(): T | undefined {
        return this.items.pop();
    }
    
    peek(): T | undefined {
        return this.items[this.items.length - 1];
    }
}

const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 2

const stringStack = new Stack<string>();
stringStack.push("hello");

7.4 泛型工具类型

typescript

复制代码
// Partial<T> - 将所有属性变为可选
interface Todo {
    title: string;
    description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
    return { ...todo, ...fieldsToUpdate };
}

// Readonly<T> - 将所有属性变为只读
const todo: Readonly<Todo> = {
    title: "Learn TS",
    description: "Study TypeScript"
};
// todo.title = "New title"; // 错误

// Pick<T, K> - 选取部分属性
type TodoPreview = Pick<Todo, "title">;

// Record<K, T> - 创建键值对类型
type PageInfo = Record<string, string>;
const pages: PageInfo = {
    home: "/home",
    about: "/about"
};

八、TypeScript 项目配置

8.1 初始化配置文件

bash

复制代码
# 生成 tsconfig.json
tsc --init

8.2 核心配置选项

json

复制代码
{
  "compilerOptions": {
    // 语言和环境
    "target": "ES2020",           // 编译目标版本
    "lib": ["ES2020", "DOM"],     // 包含的库文件
    "module": "commonjs",          // 模块系统
    "moduleResolution": "node",    // 模块解析策略
    
    // 输出配置
    "outDir": "./dist",            // 输出目录
    "rootDir": "./src",            // 源码目录
    "removeComments": true,        // 移除注释
    
    // 严格模式(推荐全部开启)
    "strict": true,                // 启用所有严格检查
    "noImplicitAny": true,         // 禁止隐式 any
    "strictNullChecks": true,      // 严格空值检查
    "strictFunctionTypes": true,   // 严格函数类型检查
    
    // 额外检查
    "noUnusedLocals": true,        // 未使用的局部变量报错
    "noUnusedParameters": true,    // 未使用的参数报错
    "noImplicitReturns": true,     // 函数缺少返回值报错
    
    // 模块解析
    "esModuleInterop": true,       // 兼容 CommonJS 和 ES 模块
    "skipLibCheck": true,          // 跳过声明文件检查
    "forceConsistentCasingInFileNames": true  // 强制文件名大小写一致
  },
  "include": ["src/**/*"],         // 包含的文件
  "exclude": ["node_modules", "dist"]  // 排除的文件
}

8.3 项目结构示例

text

复制代码
my-ts-project/
├── src/
│   ├── models/
│   │   └── user.ts
│   ├── services/
│   │   └── api.ts
│   └── index.ts
├── dist/               # 编译输出
├── tsconfig.json
├── package.json
└── .gitignore

8.4 使用 npm 脚本

json

复制代码
{
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch",
    "start": "node dist/index.js",
    "dev": "tsc --watch & nodemon dist/index.js"
  },
  "devDependencies": {
    "typescript": "^5.0.0",
    "@types/node": "^20.0.0"
  }
}

九、实际应用示例

9.1 结合 Express 使用

typescript

复制代码
import express, { Request, Response } from 'express';

interface User {
    id: number;
    name: string;
    email: string;
}

const app = express();
app.use(express.json());

const users: User[] = [];

app.get('/users', (req: Request, res: Response) => {
    res.json(users);
});

app.post('/users', (req: Request, res: Response) => {
    const { name, email } = req.body;
    const newUser: User = {
        id: users.length + 1,
        name,
        email
    };
    users.push(newUser);
    res.status(201).json(newUser);
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

9.2 类型声明文件(.d.ts)

typescript

复制代码
// types.d.ts - 为第三方库或全局变量提供类型
declare module 'my-library' {
    export function doSomething(param: string): number;
}

// 声明全局变量
declare const __VERSION__: string;
declare const __API_URL__: string;

十、最佳实践总结

  1. 开启严格模式"strict": true 捕获更多潜在错误

  2. 避免使用 any :使用 unknown 或具体类型代替

  3. 善用类型推断:让 TypeScript 自动推断简单类型

  4. 接口优先 :定义对象结构时优先使用 interface

  5. 泛型复用:为可复用逻辑编写泛型组件

  6. 明确函数返回类型:显式标注返回值提高可读性

  7. 使用可选链和空值合并?.?? 简化空值处理

  8. 定期更新 TypeScript:获取最新特性和性能改进

结语

TypeScript 已经成为现代前端和后端(Node.js)开发的标准工具。掌握 TypeScript 不仅能提高代码质量,还能让你在团队协作中更加高效。建议你在实际项目中逐步应用这些知识,从简单的类型注解开始,逐渐过渡到高级类型和泛型的使用。

推荐学习资源:

本文完,希望对你学习 TypeScript 有所帮助!欢迎在评论区交流讨论。

相关推荐
❀搜不到1 小时前
ubuntu 更新cmake
linux·运维·ubuntu
LinuxRos1 小时前
从 MCU 到 Linux:机器人嵌入式OTA升级原理解密
linux·单片机·嵌入式硬件·物联网·iot
志栋智能1 小时前
安全超自动化如何支持业务快速安全地创新?
运维·安全·自动化
console.log('npc')1 小时前
git发版上线的时候,打tag标签方便jenkins部署
运维·git·jenkins
Frank_refuel1 小时前
Linux网络之网络编程套接字
linux·运维·网络
lisanmengmeng1 小时前
gitlab 配置的jenkins 链接错误
运维·gitlab·jenkins
week@eight1 小时前
Linux - Kafka
linux·kafka
zzzsde2 小时前
【Linux网络】传输层协议UDP
linux·服务器·开发语言·网络·算法·udp
格发许可优化管理系统2 小时前
解决Mentor许可冲突,让您的业务无缝运行
运维·服务器·c语言·c++·人工智能