TypeScript(TS)是 JavaScript 的超集,核心是静态类型检查,能在编译时提前发现类型错误,大幅提升大型项目的可维护性与开发效率。以下从环境搭建、核心语法、实战项目、工程化配置、框架集成全流程讲解,附可直接运行的代码与最佳实践。
一、本地环境搭建(必备)
1. 基础安装
先安装 Node.js(v14+),再全局安装 TypeScript 编译器:
# 全局安装TS
npm install -g typescript
# 验证安装(查看版本)
tsc -v
2. 初始化 TS 项目
# 1. 创建项目并初始化
mkdir ts-project && cd ts-project
npm init -y
# 2. 生成TS配置文件(tsconfig.json)
tsc --init
3. 关键 tsconfig.json 配置(实战必改)
{
"compilerOptions": {
"target": "ES6", // 编译目标JS版本
"module": "ES6", // 模块规范
"outDir": "./dist", // 编译输出目录
"rootDir": "./src", // 源码目录
"strict": true, // 开启严格模式(核心!)
"esModuleInterop": true,// 兼容CommonJS/ES模块
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"], // 编译范围
"exclude": ["node_modules"]// 排除目录
}
4. 编译与运行
# 编译所有TS文件(src→dist)
tsc
# 监听文件变化自动编译
tsc --watch
# 运行编译后的JS
node dist/index.js
二、核心实战语法(高频使用)
1. 基础类型注解(变量/函数)
// 基础类型
let name: string = "TypeScript"
let age: number = 18
let isDone: boolean = false
let u: undefined = undefined
let n: null = null
// 数组(两种写法)
let arr1: number[] = [1, 2, 3]
let arr2: Array<string> = ["a", "b"]
// 元组(固定类型+长度的数组)
let tuple: [string, number] = ["TS", 10]
// 枚举(常量集合)
enum Status { Success, Fail, Pending }
let res: Status = Status.Success
// 函数:参数+返回值类型
function add(a: number, b: number): number {
return a + b
}
// 无返回值:void
function log(msg: string): void {
console.log(msg)
}
2. 接口(Interface):对象类型规范
核心作用:定义对象/类的结构,实现类型复用与约束
// 定义Todo接口
interface Todo {
id: number;
text: string;
done: boolean;
desc?: string; // ? 可选属性
readonly createTime: Date; // 只读属性
}
// 使用接口约束对象
const todo: Todo = {
id: 1,
text: "学习TS",
done: false,
createTime: new Date()
}
3. 类型别名(Type):复用复杂类型
// 联合类型
type Status = "success" | "fail" | "pending"
// 交叉类型
type User = { id: number } & { name: string }
// 函数类型别名
type Fn = (a: number, b: number) => number
const add: Fn = (x, y) => x + y
4. 泛型(Generic):类型参数化(复用+安全)
// 泛型函数:支持任意类型,保留类型信息
function identity<T>(arg: T): T {
return arg
}
// 使用
const str = identity<string>("TS")
const num = identity<number>(100)
// 泛型接口
interface Res<T> {
code: number;
data: T;
msg: string;
}
// 约束返回数据类型
const userRes: Res<{ name: string }> = {
code: 200,
data: { name: "张三" },
msg: "成功"
}
5. 高级类型(实战常用)
- 类型断言:手动指定类型(避免滥用)
const el = document.getElementById("app") as HTMLDivElement - 可选链(?.)与空值合并(??)
// 安全访问嵌套属性 const name = user?.info?.name // 空值时取默认值(区别于||) const age = user.age ?? 18 - 类型守卫:缩小类型范围
function isString(x: unknown): x is string { return typeof x === "string" }
三、入门实战:TodoList 纯 TS 项目
1. 项目结构
ts-todolist/
├── src/
│ ├── types.ts # 类型定义
│ ├── todo.ts # 业务逻辑
│ └── index.ts # 入口
├── tsconfig.json
└── package.json
2. 代码实现
(1)src/types.ts(定义类型)
// Todo类型
export interface Todo {
id: number;
content: string;
completed: boolean;
createTime: Date;
}
// 操作类型
export type TodoAction =
| { type: "ADD"; payload: string }
| { type: "TOGGLE"; payload: number }
| { type: "DELETE"; payload: number }
(2)src/todo.ts(核心逻辑)
import { Todo, TodoAction } from "./types"
// 初始数据
let todos: Todo[] = []
// reducer:处理Todo操作
function todoReducer(state: Todo[], action: TodoAction): Todo[] {
switch (action.type) {
case "ADD":
return [...state, {
id: Date.now(),
content: action.payload,
completed: false,
createTime: new Date()
}]
case "TOGGLE":
return state.map(todo =>
todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
)
case "DELETE":
return state.filter(todo => todo.id !== action.payload)
default:
return state
}
}
// 导出操作方法
export const addTodo = (content: string) => {
todos = todoReducer(todos, { type: "ADD", payload: content })
}
export const toggleTodo = (id: number) => {
todos = todoReducer(todos, { type: "TOGGLE", payload: id })
}
export const deleteTodo = (id: number) => {
todos = todoReducer(todos, { type: "DELETE", payload: id })
}
export const getTodos = () => [...todos]
(3)src/index.ts(入口调用)
import { addTodo, toggleTodo, deleteTodo, getTodos } from "./todo.js"
// 测试功能
addTodo("学习TS基础")
addTodo("完成Todo项目")
toggleTodo(1)
deleteTodo(2)
console.log("当前Todo列表:", getTodos())
3. 运行
tsc && node dist/index.js
效果:控制台输出类型安全的 Todo 列表,任何类型错误(如传字符串给 id)编译时直接报错。
四、进阶实战:React + TS 项目(主流)
1. 初始化 React+TS 项目
# Vite(推荐,快)
npm create vite@latest ts-react-todo -- --template react-ts
# 或 Create React App
npx create-react-app ts-react-todo --template typescript
cd ts-react-todo
npm install
npm run dev
2. 核心代码(组件+类型)
(1)src/types/index.ts
export interface Todo {
id: number;
text: string;
done: boolean;
}
(2)src/components/TodoItem.tsx
import { Todo } from "../types"
// Props类型约束
interface TodoItemProps {
todo: Todo;
onToggle: (id: number) => void;
onDelete: (id: number) => void;
}
const TodoItem: React.FC<TodoItemProps> = ({ todo, onToggle, onDelete }) => {
return (
<div style={{ textDecoration: todo.done ? "line-through" : "none" }}>
<input
type="checkbox"
checked={todo.done}
onChange={() => onToggle(todo.id)}
/>
<span>{todo.text}</span>
<button onClick={() => onDelete(todo.id)}>删除</button>
</div>
)
}
export default TodoItem
(3)src/App.tsx
import { useState } from "react"
import { Todo } from "./types"
import TodoItem from "./components/TodoItem"
function App() {
// 状态类型:Todo数组
const [todos, setTodos] = useState<Todo[]>([
{ id: 1, text: "React+TS实战", done: false }
])
const [inputText, setInputText] = useState("")
// 添加Todo
const addTodo = (e: React.FormEvent) => {
e.preventDefault()
if (!inputText.trim()) return
const newTodo: Todo = {
id: Date.now(),
text: inputText,
done: false
}
setTodos([...todos, newTodo])
setInputText("")
}
return (
<div style={{ padding: 20 }}>
<h1>TS+React Todo</h1>
<form onSubmit={addTodo}>
<input
value={inputText}
onChange={(e) => setInputText(e.target.value)}
placeholder="输入任务"
/>
<button type="submit">添加</button>
</form>
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onToggle={(id) => setTodos(todos.map(t => t.id === id ? { ...t, done: !t.done } : t))}
onDelete={(id) => setTodos(todos.filter(t => t.id !== id))}
/>
))}
</div>
)
}
export default App
优势:组件 Props、状态、事件全类型约束,编辑器自动补全,重构零风险。
五、工程化实战配置(企业级)
1. ESLint + Prettier(代码规范)
# 安装依赖
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier
.eslintrc.js:TS 代码检查规则.prettierrc:代码格式化规则
2. 第三方库类型支持
- 官方库:自带
.d.ts类型文件 - 非官方库:安装类型声明
npm install -D @types/lodash @types/react @types/node
3. 绝对路径别名(简化导入)
// tsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@/*": ["*"]
}
}
}
使用:import { Todo } from "@/types"
六、实战最佳实践(避坑)
- 必须开启
strict: true:包含noImplicitAny、strictNullChecks,彻底杜绝隐式 any 与空值错误。 - 优先类型推导:简单变量(
let num=1)无需注解,复杂对象/函数显式注解。 - 类型抽离复用:公共接口/类型放
src/types,避免重复定义。 - 少用 any:用
unknown替代,配合类型守卫保证安全。 - 泛型约束复杂逻辑:工具函数、请求返回值用泛型,兼顾灵活与安全。
- 异步处理:
Promise<T>明确返回类型,async/await配合类型守卫。
七、进阶实战方向(提升)
- 全栈:NestJS(TS 后端框架)+ Vue/React + TS
- 状态管理:Redux Toolkit + TS、Pinia + TS
- 工具库:用 TS 开发通用工具库,发布 npm 包
- 迁移:JS 老项目渐进式迁移 TS(
allowJs: true)
八、总结
TypeScript 实战核心是**「类型约束 + 工程化 + 框架集成」**:先掌握基础类型、接口、泛型,再通过 TodoList 等小项目练手,最后结合 React/Vue/NestJS 落地企业级开发。坚持严格模式与类型规范,能彻底解决 JS 动态类型的痛点,大幅提升代码质量与开发效率。