TypeScript 学习路径
本文档提供从入门到进阶的 TypeScript 学习路线,适合有 JavaScript 基础的开发者。
目录
阶段一:基础入门(1-2周)
1. 前置准备
- 熟悉 JavaScript (ES6+ 语法)
- 理解基本编程概念
2. 核心基础
typescript
// 基本类型
let name: string = "Frank"
let age: number = 30
let isActive: boolean = true
// 数组与元组
let list: number[] = [1, 2, 3]
let tuple: [string, number] = ["hello", 10]
// 枚举
enum Color { Red, Green, Blue }
// any 与 unknown
let anything: any = "could be anything"
let safe: unknown = "type-safe"
3. 函数类型
typescript
function greet(name: string): string {
return `Hello, ${name}`
}
// 箭头函数
const add = (a: number, b: number): number => a + b
// 可选参数与默认值
function buildName(first: string, last?: string): string {
return last ? `${first} ${last}` : first
}
阶段二:接口与类型别名(1-2周)
1. 接口 (Interface)
typescript
interface User {
id: number
name: string
readonly email: string // 只读属性
age?: number // 可选属性
}
// 接口扩展
interface Admin extends User {
permissions: string[]
}
2. 类型别名 (Type Alias)
typescript
type ID = string | number
type Point = { x: number; y: number }
// 联合类型
type Status = "pending" | "approved" | "rejected"
3. 接口 vs 类型别名
| 特性 | Interface | Type Alias |
|---|---|---|
| 扩展性 | 可扩展 (extends) |
可交叉 (&) |
| 声明合并 | 支持 | 不支持 |
| 对象形状 | ✅ 适合 | ✅ 支持 |
| 联合类型 | ❌ 不支持 | ✅ 支持 |
| 映射类型 | ❌ 不支持 | ✅ 支持 |
选择建议:
- 定义对象形状 → 优先使用
interface - 联合类型、映射类型、工具类型 → 使用
type
阶段三:高级类型(2-3周)
1. 泛型 (Generics)
typescript
// 基础泛型
function identity<T>(arg: T): T {
return arg
}
// 泛型约束
function getLength<T extends { length: number }>(arg: T): number {
return arg.length
}
// 泛型接口
interface Container<T> {
value: T
}
// 泛型类
class Box<T> {
constructor(public content: T) {}
}
2. 类型守卫与类型断言
typescript
// 类型守卫
function isString(val: unknown): val is string {
return typeof val === "string"
}
// 使用类型守卫
function process(val: unknown) {
if (isString(val)) {
console.log(val.toUpperCase()) // TypeScript 知道 val 是 string
}
}
// 类型断言
let value: unknown = "hello"
let len: number = (value as string).length
// 非空断言
let element = document.getElementById("app")!
3. 交叉类型
typescript
type Employee = User & {
department: string
salary: number
}
// 合并多个类型
type FullProfile = User & Admin & { createdAt: Date }
阶段四:类型体操(2-4周)
1. 映射类型 (Mapped Types)
typescript
// 基础映射
type Readonly<T> = { readonly [P in keyof T]: T[P] }
type Partial<T> = { [P in keyof T]?: T[P] }
type Required<T> = { [P in keyof T]-?: T[P] }
// 实际应用
interface Todo {
title: string
description: string
completed: boolean
}
type ReadonlyTodo = Readonly<Todo>
type PartialTodo = Partial<Todo>
2. 条件类型 (Conditional Types)
typescript
// 基础条件类型
type IsString<T> = T extends string ? true : false
type A = IsString<string> // true
type B = IsString<number> // false
// infer 关键字 - 类型推断
type ReturnType<T> = T extends (...args: any) => infer R ? R : never
type UnwrapArray<T> = T extends Array<infer U> ? U : T
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T
// 实际应用
function fn() { return "hello" }
type R = ReturnType<typeof fn> // string
type Item = UnwrapArray<string[]> // string
type Resolved = UnwrapPromise<Promise<number>> // number
3. 内置工具类型
typescript
// Pick - 选取属性
type UserPreview = Pick<User, "id" | "name">
// Omit - 排除属性
type UserWithoutEmail = Omit<User, "email">
// Record - 构造对象类型
type UserMap = Record<string, User>
// Exclude - 排除联合类型
type NonString = Exclude<string | number | boolean, string> // number | boolean
// Extract - 提取联合类型
type StringOnly = Extract<string | number | boolean, string> // string
// NonNullable - 排除 null/undefined
type NonNull = NonNullable<string | null | undefined> // string
// Parameters - 获取函数参数类型
type FnParams = Parameters<(a: string, b: number) => void> // [string, number]
// InstanceType - 获取构造函数实例类型
type DateInstance = InstanceType<typeof Date>
4. 模板字面量类型
typescript
type EventName = "click" | "focus" | "blur"
type Handler = `on${Capitalize<EventName>}`
// "onClick" | "onFocus" | "onBlur"
type Greeting = `hello ${string}` // `hello ${string}`
阶段五:实战进阶(持续)
1. 声明文件 (.d.ts)
typescript
// 全局声明
declare function myLib(options: MyLibOptions): void
interface MyLibOptions {
debug?: boolean
timeout?: number
}
// 模块声明
declare module "my-library" {
export function doSomething(input: string): number
export interface Config {
apiKey: string
}
export default class MyLibrary {
constructor(config: Config)
run(): Promise<void>
}
}
// 扩展全局对象
declare global {
interface Window {
myCustomProperty: string
}
}
2. 类型推导与断言技巧
typescript
// satisfies 操作符 (TS 4.9+)
const config = {
host: "localhost",
port: 8080
} satisfies Record<string, string | number>
// config.host 类型为 string,而不是 string | number
// const 断言
const point = { x: 10, y: 20 } as const
// 类型变为 { readonly x: 10; readonly y: 20 }
const colors = ["red", "green", "blue"] as const
// 类型变为 readonly ["red", "green", "blue"]
3. 工程化配置
json
// tsconfig.json 核心配置
{
"compilerOptions": {
/* 基础选项 */
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM"],
/* 严格模式 */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
/* 额外检查 */
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
/* 模块解析 */
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
/* 输出 */
"outDir": "./dist",
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4. 项目结构最佳实践
project/
├── src/
│ ├── types/ # 类型定义
│ │ ├── index.d.ts
│ │ └── api.d.ts
│ ├── utils/ # 工具函数
│ ├── components/ # 组件
│ └── index.ts
├── tsconfig.json
└── package.json
学习资源推荐
| 阶段 | 资源 | 说明 |
|---|---|---|
| 入门 | TypeScript 官方手册 | 最权威的入门资料 |
| 进阶 | TypeScript Deep Dive | 深入理解 TypeScript |
| 类型体操 | type-challenges | 刷题提升类型能力 |
| 实战 | Vue 3 / React / NestJS 源码 | 学习优秀项目的类型设计 |
| 工具 | TypeScript Playground | 在线练习和调试 |
学习建议
1. 边学边练
每个概念都写代码验证,不要只看不练。
2. 开启 strict 模式
json
{
"compilerOptions": {
"strict": true
}
}
强迫自己写类型安全的代码,遇到报错不要用 any 逃避。
3. 刷 type-challenges
从 easy 到 hard 循序渐进:
- Easy: 基础工具类型实现
- Medium: 条件类型、映射类型综合运用
- Hard: 复杂类型推导
4. 阅读优秀源码
推荐阅读:
- Vue 3 响应式系统类型设计
- React 类型定义
- NestJS 装饰器类型
5. 遇到报错别用 any
理解为什么报错,找到正确的解决方案:
- 使用类型守卫
- 使用类型断言
- 使用泛型约束
- 使用 unknown 替代 any
学习时间线
| 阶段 | 内容 | 预计时间 |
|---|---|---|
| 阶段一 | 基础类型、函数类型 | 1-2 周 |
| 阶段二 | 接口、类型别名 | 1-2 周 |
| 阶段三 | 泛型、类型守卫 | 2-3 周 |
| 阶段四 | 类型体操 | 2-4 周 |
| 阶段五 | 实战项目 | 持续 |
总计:约 2-3 个月可掌握核心能力。
常见问题
Q: interface 和 type 有什么区别?
A: 主要区别在于:
interface可以声明合并,type不行interface使用extends扩展,type使用&交叉type支持联合类型、映射类型等更复杂的类型操作
Q: 什么时候用 any?什么时候用 unknown?
A:
- 尽量避免使用
any,它会关闭类型检查 - 优先使用
unknown,它需要类型守卫才能使用
Q: 如何处理第三方库没有类型定义?
A:
- 安装
@types/package-name - 创建本地
.d.ts声明文件 - 使用
declare module快速声明
文档创建时间: 2026-04-12