全栈开发学习教程
前端 TypeScript + 后端 Python,从零到独立开发全栈应用
全部中文注释 · GSAP 动画讲解 · Remotion 风逐行代码播放器
为什么选 TypeScript + Python?
这是 2025 年独立开发者性价比最高的技术组合:
| 层 | 语言 | 框架 | 理由 |
|---|---|---|---|
| 前端 | TypeScript | Next.js + React | 前端世界就这一门语言,TS 是加了类型系统的 JS |
| 后端 | Python | FastAPI | 学习曲线最低、AI 生态最强、自动化脚本王者 |
不要同时学两门语言。先学 TypeScript(2-4 周基础),再学 Python(2-4 周基础),最后做全栈项目把两者连起来。每章都有练习和动画播放器,做完再往下走。
你需要一台电脑,安装好 Node.js 和 Python:nodejs.org 和 python.org。
★ 写给完全没碰过代码的你
如果你看到 let name = "小明" 就头大,这一章就是给你写的。先读这章,再开始第 1 节。
一个最大的秘密:编程只是 6 个动作
你看到的所有程序——无论淘宝、抖音、Excel 公式还是 AI——都只是这 6 个动作的不同组合:
| 动作 | 生活中你在干嘛 | 编程叫什么 |
|---|---|---|
| ① 把一个东西存起来,记住它的名字 | 把客户电话写在笔记本上,标注"张三" | 变量 |
| ② 按条件决定做不做 | "如果张三还钱,今天就发货;否则再等等" | if 条件 |
| ③ 重复做同一件事 | 每天把店里 30 件商品各擦一遍 | 循环 |
| ④ 写一份 SOP 标准流程 | 新员工入职,照着"接单流程"做 | 函数 |
| ⑤ 把一堆同类的东西排成一列 | 手机里的通讯录清单 | 数组/列表 |
| ⑥ 给一份资料贴上标签方便查找 | 客户档案袋上写"姓名/电话/地址" | 对象/字典 |
"程序 = 数据 + 处理步骤"。不管代码多复杂,拆开看就是:先有几个数据(变量/数组/对象),然后告诉电脑怎么处理它们(if/循环/函数)。
6 个动作的可视化(滚动看每个)
① 变量 = 贴了标签的盒子
你给一个盒子贴个标签,盒子里面装一个东西。变量 = 一个盒子,标签 = 名字,里面装的东西 = 值。
代码:name = "小明"
② if 条件 = 现实选择题
你在店里天天做:「如果下雨就关门打烊,否则正常营业」。编程里叫 if / else。
③ 循环 = 流水线机器
你每天早上要把店里 30 件商品各擦一遍——你不会写 30 行"擦商品"代码,而是写一遍"擦商品"的指令,告诉电脑重复 30 次。
「对这 4 件商品,每件都做"展示价格"」
④ 函数 = SOP 标准作业流程
新员工入职,你给他一张流程单:「输入客户姓名 → 查系统 → 发短信」。这张流程单就是 函数——输入材料(参数),按步骤做,输出结果(返回值)。
⑤ 数组/列表 = 通讯录清单
通讯录本质上是一张按顺序排列的清单:第 1 位张三,第 2 位李四,第 3 位王五。代码里叫 数组 / 列表(list)。
| 序号 | 名字 | 电话 |
|---|---|---|
| 0 | 张三 | 138-xxxx |
| 1 | 李四 | 139-xxxx |
| 2 | 王五 | 156-xxxx |
代码:contacts = ["张三", "李四", "王五"] 第 1 位是 contacts[0]
⑥ 对象/字典 = 档案袋
每个客户有个档案袋,上面贴着"姓名/电话/地址"三张标签,每个标签对应一个值。这叫对象 / 字典(dict)——标签叫"键",内容叫"值"。
代码:user["电话"] → "138-1234"
🎁 学完整个教程你能干什么?
比如把你家的卤菜、农产品、家宴服务挂到网上,让人能直接下单付款
批量下载竞品视频、采集爆款文案、自动筛选评论
用 Whisper 把你的视频转字幕、用 GPT 自动写你的产品文案
你姐、好友的店要做小程序、要获客——你都能接
第 1 章和第 5 章是新手最容易卡住的——里面已经加了「人话翻译」卡片,看到代码先读卡片,再读代码。每段代码最长 5 行,超出 5 行的我都加了拆解说明。别急,慢慢来。
学习路线图
按顺序走,每一步都有明确的产出物。不要跳步。
TypeScript 基础(第 1-4 章)
理解类型系统、接口、函数类型、联合类型、泛型。产出:能用 TS 写出带类型的小程序。
JavaScript 实战(第 5-7 章)
掌握变量、数组方法、对象解构、async/await。产出:能用 JS 操控 DOM、发请求、处理数据。
Python 基础(第 8-11 章)
变量、数据结构、函数、文件操作、面向对象。产出:能用 Python 写脚本和数据处理程序。
FastAPI 后端(第 12-13 章)
创建 API、路由参数、Pydantic 验证、CRUD 操作。产出:能跑起一个带文档的后端 API 服务。
全栈联调(第 14 章)
前端 TS 调后端 Python API,完成增删改查。产出:一个能跑的全栈 Demo。
1. TypeScript 是什么
TypeScript(简称 TS)是 JavaScript 的超集,简单说就是"加了类型系统的 JavaScript"。你写的 TS 代码最终会被编译成 JS 来运行。
为什么不用纯 JavaScript?
/* JS 不检查参数类型,传错了运行时才暴露 */ function add(a, b) { return a + b; } add(1, "2"); /* 返回 "12",不是 3!JS 不会报错 */
/* TS 在写代码时就告诉你类型对不对 */ function add(a: number, b: number): number { return a + b; } add(1, "2"); /* ❌ 编辑器直接红线报错!数字+字符串 */
TypeScript 的核心价值:在代码运行之前就发现错误。越早发现 bug,修复成本越低。大型项目中用 TS 已是标配。
安装 TypeScript
/* 全局安装 TypeScript 编译器 */ npm install -g typescript /* 验证安装是否成功 */ tsc --version
第一个 TS 程序
/* 定义一个接口:描述"用户"对象长什么样 */ interface User { name: string; age: number; } /* 函数接收 User 类型参数,返回字符串 */ function greet(user: User): string { return `你好,${user.name},你 ${user.age} 岁了`; } const me: User = { name: "小明", age: 25 }; console.log(greet(me)); /* 输出:你好,小明,你 25 岁了 */
/* 编译 TS → JS,生成 hello.js */ tsc hello.ts /* 用 Node.js 运行编译后的 JS */ node hello.js
2. 基础类型系统
TypeScript 的核心就是类型标注——告诉编译器每个变量是什么类型。下面用 Remotion 风逐行动画播放器 一步步讲解:
类型推断
其实很多时候你不需要手动写类型。TS 会自动推断:let x = 42 自动推断 x 是 number。只有函数参数、复杂对象等才需要显式标注。
3. 函数与接口
函数类型
/* 参数和返回值都可以标注类型 */ function add(a: number, b: number): number { return a + b; } /* 箭头函数也可以加类型 */ const multiply = (a: number, b: number): number => a * b; /* 可选参数:加 ? */ function greet(name: string, greeting?: string): string { return `${greeting ?? "你好"},${name}`; } /* 参数默认值:不传就用默认值 */ function createUser(name: string, role: string = "user") { return { name, role }; }
接口(Interface)
接口用来定义对象的形状——它有哪些字段、每个字段是什么类型。
/* 定义一个接口,描述"用户"对象的形状 */ interface User { id: number; name: string; email: string; avatar?: string; /* 可选字段(加 ?) */ readonly createdAt: Date; /* 只读字段,创建后不能改 */ } /* 使用接口:必须提供 id/name/email/createdAt */ const user: User = { id: 1, name: "小明", email: "xm@test.com", createdAt: new Date() /* avatar 不写也行,因为它是可选的 */ }; /* user.createdAt = new Date(); ← ❌ 报错:只读字段不能修改 */
interface 和 type 都能定义对象类型。区别:interface 可以被"继承"(extends),初学建议先用 interface。
4. 联合类型与泛型
联合类型(Union Types)
一个变量可以是多种类型之一,用 | 连接。
/* id 可以是数字或字符串 */ let id: number | string; id = 123; /* ✅ 数字可以 */ id = "abc"; /* ✅ 字符串也可以 */ /* id = true; ← ❌ 布尔值不行! */ /* 字面量类型:只能是这几个固定值 */ type Status = "pending" | "active" | "deleted"; let userStatus: Status = "active"; /* ✅ */ /* userStatus = "banned"; ← ❌ 不在联合范围内 */
泛型(Generics)
泛型就是"类型版的变量"——普通变量存值,泛型存类型。
/* T 是类型占位符,用的时候才确定具体类型 */ function first<T>(arr: T[]): T { return arr[0]; } const n = first([1, 2, 3]); /* n 自动推断为 number */ const s = first(["a", "b"]); /* s 自动推断为 string */ /* 泛型接口:统一的后端响应格式 */ interface ApiResponse<T> { code: number; data: T; message: string; }
泛型看起来吓人,其实就是"类型版的变量"。先读一遍代码,看多了自然就懂了。
const result = wrap(42);中,result 的类型?5. JavaScript 核心语法
TypeScript 最终编译成 JavaScript 运行。下面是 JS 核心语法,你可以在浏览器里直接运行。
/* const: 不可重新赋值(推荐默认用 const) */ const name = "小明"; /* let: 可重新赋值 */ let age = 25; age = 26; /* ✅ 可以改 */ /* var: 老写法,有作用域问题,不要用了 */ /* 模板字符串:用反引号 + ${} 嵌入变量 */ console.log(`${name} 今年 ${age} 岁`);
下面代码在干啥:把"小明"装进叫 name 的盒子,25 装进 age,然后用 console.log 把"你好 小明,你今年 25 岁"打印到下方。
怎么改:把引号里的"小明"改成你的名字,把 25 改成你的年龄,点 ▶运行 看变化。
6. 数组与对象
数组方法
const nums = [1, 2, 3, 4, 5]; /* map: 对每个元素做变换,返回新数组 */ const doubled = nums.map(n => n * 2); /* [2, 4, 6, 8, 10] */ /* filter: 过滤符合条件的元素 */ const evens = nums.filter(n => n % 2 === 0); /* [2, 4] */ /* reduce: 累加计算 */ const sum = nums.reduce((acc, n) => acc + n, 0); /* 15 */ /* find: 找第一个满足条件的元素 */ const found = nums.find(n => n > 3); /* 4 */ /* forEach: 遍历每个元素(不返回新数组) */ nums.forEach(n => console.log(n));
对象与解构
const user = { name: "小明", age: 25, city: "广元市旺苍县" }; /* 解构赋值:一次性取出多个字段 */ const { name, city } = user; console.log(name, city); /* 小明 广元市旺苍县 */ /* 展开运算符:复制对象并修改部分字段 */ const updated = { ...user, age: 26 }; console.log(updated); /* { name: "小明", age: 26, city: "广元市旺苍县" } */
7. 异步编程 — Remotion 逐行讲解
JavaScript 是单线程的,但通过异步机制可以处理网络请求、文件读写等耗时操作。
Promise 有三种状态:pending(等待中)→ fulfilled(成功)/ rejected(失败)。await 只能在 async 函数里用,它会暂停执行直到 Promise 完成。
8. Python 基础
Python 语法接近自然语言,是最适合入门的编程语言。
变量与字符串
# 变量不需要声明类型(Python 是动态类型) name = "小明" age = 25 height = 1.75 is_student = True # 布尔值,注意首字母大写 # f-string(类似 JS 模板字符串) print(f"{name} 今年 {age} 岁,身高 {height} 米") # 多行字符串:用三个引号 text = """这是 多行 文本""" # 字符串常用方法 print("hello".upper()) # 转大写:HELLO print(" hi ".strip()) # 去空格:hi print("a,b,c".split(",")) # 分割:['a', 'b', 'c']
控制流
score = 85 # if / elif / else — 用冒号开头,缩进表层级 if score >= 90: print("优秀") elif score >= 80: print("良好") elif score >= 60: print("及格") else: print("不及格") # for 循环:range(5) 生成 0~4 for i in range(5): print(i) # 输出 0 1 2 3 4(每行一个) # while 循环:条件为真就一直跑 count = 0 while count < 3: print(f"当前 count = {count}") count += 1
| 概念 | Python | JavaScript |
|---|---|---|
| 变量声明 | x = 1 | let x = 1 |
| 代码块 | 缩进(4 空格) | { } 大括号 |
| 布尔值 | True / False | true / false |
| 空值 | None | null / undefined |
| 条件链 | if / elif / else | if / else if / else |
| 字符串格式化 | f"{x}" | `${x}` |
9. Python 数据结构 — 逐行讲解
列表(List)
fruits = ["苹果", "香蕉", "橙子"] fruits.append("葡萄") # 末尾添加元素 fruits.insert(0, "西瓜") # 在指定位置插入 fruits.remove("香蕉") # 删除指定元素 print(fruits[0]) # 访问第一个 print(fruits[-1]) # 访问最后一个(负数从末尾计) print(len(fruits)) # 获取长度
字典(Dict)— Python 核心数据结构
10. 函数与文件操作
函数
# 基本函数定义 def add(a, b): return a + b # 默认参数:不传就用默认值 def greet(name, greeting="你好"): return f"{greeting},{name}" print(greet("小明")) # 输出:你好,小明 print(greet("小明", "哈喽")) # 输出:哈喽,小明 # 不定长参数:*args 接收任意数量参数 def sum_all(*numbers): return sum(numbers) print(sum_all(1, 2, 3, 4)) # 输出:10 # Lambda 匿名函数(类似 JS 箭头函数) square = lambda x: x ** 2 print(square(5)) # 输出:25
文件操作
# 写文件("w" 模式:覆盖写入) with open("data.txt", "w", encoding="utf-8") as f: f.write("第一行\n") f.write("第二行\n") # 读文件("r" 模式:只读) with open("data.txt", "r", encoding="utf-8") as f: content = f.read() # 一次性读取全部 print(content) # 逐行读取(适合大文件) with open("data.txt", "r", encoding="utf-8") as f: for line in f: print(line.strip())
用 with 打开文件,Python 会在代码块结束时自动关闭文件,不需要手动 f.close()。
11. 面向对象编程
Python 的类(class)用来创建自定义数据类型。
class Dog: # __init__ 是构造方法,创建实例时自动执行 def __init__(self, name, breed, age): self.name = name # 实例属性:每个狗名字不同 self.breed = breed # 品种 self.age = age # 年龄 # 实例方法:self 指向调用它的那只狗 def bark(self): return f"{self.name} 汪汪叫!" def birthday(self): self.age += 1 return f"{self.name} 过完生日,{self.age} 岁了" # 创建两只狗 dog1 = Dog("旺财", "中华田园犬", 3) print(dog1.bark()) # 旺财 汪汪叫! print(dog1.birthday()) # 旺财 过完生日,4 岁了
self 就是 Python 版的 this(JavaScript 里的 this)。它指向当前对象实例,每个实例方法的第一个参数必须是 self。
12. FastAPI 入门
FastAPI 是 Python 最现代的 Web 框架——性能极高、自带 API 文档、类型安全、异步支持。
安装
# 安装 FastAPI + uvicorn 服务器 pip install "fastapi[standard]" # 或用 uv(更现代的包管理器) uv add fastapi uvicorn
第一个 API
from fastapi import FastAPI app = FastAPI() # 创建应用实例 @app.get("/") # GET 请求,访问根路径 def home(): return {"message": "Hello, FastAPI!"} @app.get("/users/{user_id}") # 路径参数 {user_id} def get_user(user_id: int): return {"user_id": user_id, "name": "用户" + str(user_id)}
# 启动开发服务器(修改代码自动重载) fastapi dev main.py # 自动生成的 API 文档(直接在浏览器测试!) # http://127.0.0.1:8000/docs → Swagger UI(交互式文档) # http://127.0.0.1:8000/redoc → ReDoc(美观文档)
你定义好路由后,访问 /docs 就能在浏览器里直接测试每个接口——不需要 Postman!文档全是自动生成的。
13. CRUD 与 Pydantic 验证 — 逐行讲解
Pydantic 是 FastAPI 的数据验证库。定义模型 → 自动验证 → 生成文档,一条龙。
14. 前后端联调
前端 TypeScript 调后端 Python API——全栈开发的本质循环。
后端(Python FastAPI)
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel app = FastAPI() # 允许前端跨域访问(开发时必须加) app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) class Todo(BaseModel): title: str # 待办标题 done: bool = False # 是否完成,默认未完成 todos = [] # 演示用内存存储 @app.get("/api/todos") # 读取:获取所有待办 def get_todos(): return todos @app.post("/api/todos") # 创建:新增待办 def add_todo(todo: Todo): todos.append(todo.model_dump()) return {"ok": True}
前端(TypeScript)
/* 定义接口类型:和后端 Pydantic 模型保持一致 */ interface Todo { title: string; done: boolean; } /* 获取所有待办:GET 请求 */ async function fetchTodos(): Promise<Todo[]> { const res = await fetch("http://localhost:8000/api/todos"); return res.json(); } /* 创建新待办:POST 请求,发送 JSON body */ async function createTodo(title: string): Promise<void> { await fetch("http://localhost:8000/api/todos", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title, done: false }) }); } /* 使用示例:创建后获取列表 */ createTodo("学完这个教程").then(() => { fetchTodos().then(todos => console.log(todos)); });
用户操作 → 前端 TS 发 fetch 请求 → 后端 FastAPI 接收 → 处理后返回 JSON → 前端 TS 拿到数据 → 渲染到页面。
免费学习资源
TypeScript / 前端
Python / 后端
练习平台推荐
开源全栈项目模板
不要从零搭项目。先 clone 一个模板跑起来,然后改成自己的业务。比如用 Full Stack FastAPI Template 做后台、Next.js 做前端。
全栈开发学习教程 · TypeScript + Python · GSAP 动画 + Remotion 风代码播放器
所有内容内嵌于单个 HTML 文件,中文注释,可离线使用