Node.js之TypeScript支持

Node.js之TypeScript支持

安装 TypeScript 与 @types/node

全局安装 TypeScript

javascript 复制代码
npm install -g typescript

项目级别安装

javascript 复制代码
// 安装 TypeScript 编译器和 Node.js 类型定义
npm install --save-dev typescript @types/node

// 安装 ts-node 用于直接运行 TypeScript 文件
npm install --save-dev ts-node

// 安装其他常用类型定义
npm install --save-dev @types/express @types/lodash

验证安装

javascript 复制代码
// 查看 TypeScript 版本
tsc --version

// 查看 ts-node 版本
ts-node --version

初始化 TypeScript 配置文件

生成 tsconfig.json

javascript 复制代码
// 在项目根目录执行
tsc --init

自定义配置文件结构

javascript 复制代码
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

常用配置说明

编译选项详解

目标与模块配置
javascript 复制代码
{
  "compilerOptions": {
    // 编译目标版本
    "target": "ES2020",           // ES5, ES6, ES2017, ES2018, ES2019, ES2020, ESNext
    
    // 模块系统
    "module": "commonjs",         // commonjs, amd, system, umd, es6, es2015, es2020, esnext
    
    // 包含的库文件
    "lib": ["ES2020", "DOM"],     // 根据运行环境选择
    
    // 模块解析策略
    "moduleResolution": "node"    // node, classic
  }
}
输出配置
javascript 复制代码
{
  "compilerOptions": {
    // 输出目录
    "outDir": "./dist",
    
    // 根目录
    "rootDir": "./src",
    
    // 生成声明文件
    "declaration": true,
    
    // 生成源码映射
    "sourceMap": true,
    
    // 移除注释
    "removeComments": false
  }
}
类型检查配置
javascript 复制代码
{
  "compilerOptions": {
    // 严格模式
    "strict": true,
    
    // 不允许隐式 any
    "noImplicitAny": true,
    
    // 严格空值检查
    "strictNullChecks": true,
    
    // 严格函数类型检查
    "strictFunctionTypes": true,
    
    // 未使用变量检查
    "noUnusedLocals": true,
    
    // 未使用参数检查
    "noUnusedParameters": true
  }
}

添加 TypeScript 代码

基础类型示例

javascript 复制代码
// src/types/index.ts
export interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
  createdAt: Date;
}

export type UserRole = 'admin' | 'user' | 'guest';

export interface CreateUserDto {
  name: string;
  email: string;
  role?: UserRole;
}

服务层实现

javascript 复制代码
// src/services/userService.ts
import { User, CreateUserDto, UserRole } from '../types';

export class UserService {
  private users: User[] = [];
  private nextId = 1;

  async createUser(userData: CreateUserDto): Promise<User> {
    const user: User = {
      id: this.nextId++,
      name: userData.name,
      email: userData.email,
      isActive: true,
      createdAt: new Date()
    };
    
    this.users.push(user);
    return user;
  }

  async getUserById(id: number): Promise<User | undefined> {
    return this.users.find(user => user.id === id);
  }

  async getAllUsers(): Promise<User[]> {
    return [...this.users];
  }
}

Express 应用示例

javascript 复制代码
// src/app.ts
import express, { Request, Response, NextFunction } from 'express';
import { UserService } from './services/userService';
import { CreateUserDto } from './types';

const app = express();
const userService = new UserService();

app.use(express.json());

// 类型安全的路由处理
app.post('/users', async (req: Request<{}, User, CreateUserDto>, res: Response) => {
  try {
    const user = await userService.createUser(req.body);
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ error: (error as Error).message });
  }
});

app.get('/users/:id', async (req: Request<{ id: string }>, res: Response) => {
  const id = parseInt(req.params.id, 10);
  const user = await userService.getUserById(id);
  
  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }
  
  res.json(user);
});

export default app;

入口文件

javascript 复制代码
// src/index.ts
import app from './app';

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

编译 TypeScript 代码

编译流程图

graph TD A[TypeScript 源码] --> B[类型检查] B --> C{类型检查通过?} C -->|是| D[编译为 JavaScript] C -->|否| E[报告类型错误] D --> F[生成 .js 文件] D --> G[生成 .d.ts 声明文件] D --> H[生成 .map 源码映射] F --> I[输出到 dist 目录] G --> I H --> I

编译命令

javascript 复制代码
// 编译整个项目
tsc

// 编译特定文件
tsc src/index.ts

// 监听模式编译
tsc --watch

// 编译并忽略类型错误
tsc --noEmitOnError false

package.json 脚本配置

javascript 复制代码
{
  "scripts": {
    "build": "tsc",
    "build:watch": "tsc --watch",
    "clean": "rm -rf dist",
    "prebuild": "npm run clean"
  }
}

编译输出示例

编译前 (src/index.ts):

javascript 复制代码
import express from 'express';
const app: express.Application = express();

编译后 (dist/index.js):

javascript 复制代码
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const app = express_1.default();

在 Node.js 中运行 TypeScript 编译后的代码

运行流程图

graph TD A[npm run build] --> B[TypeScript 编译] B --> C[生成 JavaScript 文件] C --> D[node dist/index.js] D --> E[Node.js 执行] F[开发环境] --> G[ts-node src/index.ts] G --> H[直接执行 TypeScript]

生产环境运行

javascript 复制代码
// 1. 编译项目
npm run build

// 2. 运行编译后的 JavaScript
node dist/index.js

// 3. 使用 PM2 管理进程
pm2 start dist/index.js --name "my-app"

package.json 配置

javascript 复制代码
{
  "main": "dist/index.js",
  "scripts": {
    "start": "node dist/index.js",
    "start:prod": "NODE_ENV=production node dist/index.js",
    "build": "tsc",
    "prebuild": "npm run clean",
    "clean": "rm -rf dist"
  }
}

使用 ts-node 直接运行 TypeScript 文件使用 npm 脚本自动化

ts-node 配置

javascript 复制代码
// 安装 ts-node
npm install --save-dev ts-node

// 直接运行 TypeScript 文件
npx ts-node src/index.ts

// 使用特定 tsconfig
npx ts-node --project tsconfig.dev.json src/index.ts

开发环境脚本配置

javascript 复制代码
{
  "scripts": {
    "dev": "ts-node src/index.ts",
    "dev:watch": "ts-node --watch src/index.ts",
    "dev:debug": "ts-node --inspect src/index.ts",
    "test": "ts-node --project tsconfig.test.json test/index.ts"
  }
}

nodemon 集成

javascript 复制代码
// 安装 nodemon
npm install --save-dev nodemon

// nodemon.json 配置
{
  "watch": ["src"],
  "ext": "ts,json",
  "ignore": ["src/**/*.test.ts"],
  "exec": "ts-node src/index.ts"
}

// package.json 脚本
{
  "scripts": {
    "dev": "nodemon",
    "dev:debug": "nodemon --exec 'ts-node --inspect src/index.ts'"
  }
}

完整的自动化流程

graph TD A[开发阶段] --> B[ts-node + nodemon] B --> C[自动重载] C --> D[类型检查] D --> E[代码执行] F[构建阶段] --> G[tsc 编译] G --> H[类型检查] H --> I[生成 JavaScript] I --> J[生产部署] K[测试阶段] --> L[ts-node 运行测试] L --> M[Jest/Mocha 执行]

环境变量配置

javascript 复制代码
// .env 文件
NODE_ENV=development
PORT=3000
DATABASE_URL=mongodb://localhost:27017/myapp

// 在 TypeScript 中使用
import dotenv from 'dotenv';
dotenv.config();

const config = {
  port: process.env.PORT || 3000,
  nodeEnv: process.env.NODE_ENV || 'development',
  databaseUrl: process.env.DATABASE_URL
};

完整的 package.json 示例

javascript 复制代码
{
  "name": "nodejs-typescript-app",
  "version": "1.0.0",
  "description": "Node.js TypeScript 应用示例",
  "main": "dist/index.js",
  "scripts": {
    "dev": "nodemon",
    "build": "tsc",
    "start": "node dist/index.js",
    "start:prod": "NODE_ENV=production node dist/index.js",
    "clean": "rm -rf dist",
    "prebuild": "npm run clean",
    "test": "jest",
    "test:watch": "jest --watch",
    "lint": "eslint src/**/*.ts",
    "lint:fix": "eslint src/**/*.ts --fix"
  },
  "devDependencies": {
    "@types/node": "^18.0.0",
    "@types/express": "^4.17.0",
    "typescript": "^4.8.0",
    "ts-node": "^10.9.0",
    "nodemon": "^2.0.0",
    "jest": "^29.0.0",
    "@types/jest": "^29.0.0",
    "eslint": "^8.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "@typescript-eslint/eslint-plugin": "^5.0.0"
  },
  "dependencies": {
    "express": "^4.18.0",
    "dotenv": "^16.0.0"
  }
}
相关推荐
马优晨2 小时前
cssnano 在前端工程化中的应用
前端·cssnano应用·cssnano 是什么·cssnano介绍·css优化
若梦plus2 小时前
Node.js基础与常用模块
前端·node.js
若梦plus2 小时前
Node.js之进程管理child_process与cluster深度解析
前端·node.js
若梦plus2 小时前
Node.js之核心模块
前端·node.js
研☆香2 小时前
html页面如何精准布局
前端·html
零下32摄氏度2 小时前
【前端干货】接口在 Postman 测试很快,页面加载咋就慢?
前端·程序人生·postman
全栈陈序员3 小时前
说说你对 Vue 的理解
前端·javascript·vue.js·学习·前端框架
全栈技术负责人3 小时前
Ling框架:针对AIGC工作流中JSON数据流式处理的解决方案
前端·ai
自由与自然3 小时前
实现类似van-dialog自定义弹框
前端·javascript·html